commit 2866d74b32e1cff4b2585a832c56a4a69f06db61 Author: Bruno Charest Date: Sun Sep 14 23:05:30 2025 -0400 first commit diff --git a/.angular/cache/20.2.2/app/.tsbuildinfo b/.angular/cache/20.2.2/app/.tsbuildinfo new file mode 100644 index 0000000..a3f2a23 --- /dev/null +++ b/.angular/cache/20.2.2/app/.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":["../../../../node_modules/typescript/lib/lib.es5.d.ts","../../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../../node_modules/typescript/lib/lib.es2021.d.ts","../../../../node_modules/typescript/lib/lib.es2022.d.ts","../../../../node_modules/typescript/lib/lib.dom.d.ts","../../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../../node_modules/tslib/tslib.d.ts","../../../../index.ngtypecheck.ts","../../../../node_modules/@angular/core/graph.d.d.ts","../../../../node_modules/@angular/core/event_dispatcher.d.d.ts","../../../../node_modules/@angular/core/chrome_dev_tools_performance.d.d.ts","../../../../node_modules/rxjs/dist/types/internal/subscription.d.ts","../../../../node_modules/rxjs/dist/types/internal/subscriber.d.ts","../../../../node_modules/rxjs/dist/types/internal/operator.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable.d.ts","../../../../node_modules/rxjs/dist/types/internal/types.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/audit.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/audittime.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/buffer.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/buffercount.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/buffertime.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/buffertoggle.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/bufferwhen.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/catcherror.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/combinelatestall.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/combineall.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/combinelatest.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/combinelatestwith.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/concat.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/concatall.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/concatmap.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/concatmapto.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/concatwith.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/connect.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/count.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/debounce.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/debouncetime.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/defaultifempty.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/delay.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/delaywhen.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/dematerialize.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/distinct.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/distinctuntilchanged.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/distinctuntilkeychanged.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/elementat.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/endwith.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/every.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/exhaustall.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/exhaust.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/exhaustmap.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/expand.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/filter.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/finalize.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/find.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/findindex.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/first.d.ts","../../../../node_modules/rxjs/dist/types/internal/subject.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/groupby.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/ignoreelements.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/isempty.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/last.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/map.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/mapto.d.ts","../../../../node_modules/rxjs/dist/types/internal/notification.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/materialize.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/max.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/merge.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/mergeall.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/mergemap.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/flatmap.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/mergemapto.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/mergescan.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/mergewith.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/min.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/connectableobservable.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/multicast.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/observeon.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/onerrorresumenextwith.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/pairwise.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/partition.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/pluck.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/publish.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/publishbehavior.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/publishlast.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/publishreplay.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/race.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/racewith.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/reduce.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/repeat.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/repeatwhen.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/retry.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/retrywhen.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/refcount.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/sample.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/sampletime.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/scan.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/sequenceequal.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/share.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/sharereplay.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/single.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/skip.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/skiplast.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/skipuntil.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/skipwhile.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/startwith.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/subscribeon.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/switchall.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/switchmap.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/switchmapto.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/switchscan.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/take.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/takelast.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/takeuntil.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/takewhile.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/tap.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/throttle.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/throttletime.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/throwifempty.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/timeinterval.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/timeout.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/timeoutwith.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/timestamp.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/toarray.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/window.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/windowcount.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/windowtime.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/windowtoggle.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/windowwhen.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/withlatestfrom.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/zip.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/zipall.d.ts","../../../../node_modules/rxjs/dist/types/internal/operators/zipwith.d.ts","../../../../node_modules/rxjs/dist/types/operators/index.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/action.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler.d.ts","../../../../node_modules/rxjs/dist/types/internal/testing/testmessage.d.ts","../../../../node_modules/rxjs/dist/types/internal/testing/subscriptionlog.d.ts","../../../../node_modules/rxjs/dist/types/internal/testing/subscriptionloggable.d.ts","../../../../node_modules/rxjs/dist/types/internal/testing/coldobservable.d.ts","../../../../node_modules/rxjs/dist/types/internal/testing/hotobservable.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/asyncscheduler.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/timerhandle.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/asyncaction.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/virtualtimescheduler.d.ts","../../../../node_modules/rxjs/dist/types/internal/testing/testscheduler.d.ts","../../../../node_modules/rxjs/dist/types/testing/index.d.ts","../../../../node_modules/rxjs/dist/types/internal/symbol/observable.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/dom/animationframes.d.ts","../../../../node_modules/rxjs/dist/types/internal/behaviorsubject.d.ts","../../../../node_modules/rxjs/dist/types/internal/replaysubject.d.ts","../../../../node_modules/rxjs/dist/types/internal/asyncsubject.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/asapscheduler.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/asap.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/async.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/queuescheduler.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/queue.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/animationframescheduler.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduler/animationframe.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/identity.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/pipe.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/noop.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/isobservable.d.ts","../../../../node_modules/rxjs/dist/types/internal/lastvaluefrom.d.ts","../../../../node_modules/rxjs/dist/types/internal/firstvaluefrom.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/argumentoutofrangeerror.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/emptyerror.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/notfounderror.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/objectunsubscribederror.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/sequenceerror.d.ts","../../../../node_modules/rxjs/dist/types/internal/util/unsubscriptionerror.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/bindcallback.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/bindnodecallback.d.ts","../../../../node_modules/rxjs/dist/types/internal/anycatcher.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/combinelatest.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/concat.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/connectable.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/defer.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/empty.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/forkjoin.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/from.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/fromevent.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/fromeventpattern.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/generate.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/iif.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/interval.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/merge.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/never.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/of.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/onerrorresumenext.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/pairs.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/partition.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/race.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/range.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/throwerror.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/timer.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/using.d.ts","../../../../node_modules/rxjs/dist/types/internal/observable/zip.d.ts","../../../../node_modules/rxjs/dist/types/internal/scheduled/scheduled.d.ts","../../../../node_modules/rxjs/dist/types/internal/config.d.ts","../../../../node_modules/rxjs/dist/types/index.d.ts","../../../../node_modules/@angular/core/effect.d.d.ts","../../../../node_modules/@angular/core/primitives/di/index.d.ts","../../../../node_modules/@angular/core/discovery.d.d.ts","../../../../node_modules/@angular/core/api.d.d.ts","../../../../node_modules/@angular/core/weak_ref.d.d.ts","../../../../node_modules/@angular/core/index.d.ts","../../../../node_modules/@angular/common/platform_location.d.d.ts","../../../../node_modules/@angular/common/common_module.d.d.ts","../../../../node_modules/@angular/common/xhr.d.d.ts","../../../../node_modules/@angular/common/index.d.ts","../../../../node_modules/@angular/platform-browser/browser.d.d.ts","../../../../node_modules/@angular/common/module.d.d.ts","../../../../node_modules/@angular/common/http/index.d.ts","../../../../node_modules/@angular/platform-browser/index.d.ts","../../../../node_modules/@angular/router/router_module.d.d.ts","../../../../node_modules/@angular/router/index.d.ts","../../../../src/pipes/translate.pipe.ngtypecheck.ts","../../../../src/services/i18n.service.ngtypecheck.ts","../../../../src/services/i18n.service.ts","../../../../src/pipes/translate.pipe.ts","../../../../node_modules/@angular/forms/index.d.ts","../../../../src/components/header/header.component.ngtypecheck.ts","../../../../src/services/instance.service.ngtypecheck.ts","../../../../src/services/instance.service.ts","../../../../src/services/auth.service.ngtypecheck.ts","../../../../src/services/auth.service.ts","../../../../src/services/user.service.ngtypecheck.ts","../../../../src/services/user.service.ts","../../../../src/services/themes.service.ngtypecheck.ts","../../../../src/models/theme.model.ngtypecheck.ts","../../../../src/models/theme.model.ts","../../../../src/services/themes.service.ts","../../../../src/services/history.service.ngtypecheck.ts","../../../../src/services/history.service.ts","../../../../src/components/header/header.component.ts","../../../../src/components/sidebar/sidebar.component.ngtypecheck.ts","../../../../src/components/sidebar/sidebar.component.ts","../../../../src/app.component.ngtypecheck.ts","../../../../src/components/themes/themes-nav.component.ngtypecheck.ts","../../../../src/components/themes/themes-nav.component.ts","../../../../src/app.component.ts","../../../../src/app.routes.ngtypecheck.ts","../../../../src/components/themes/theme-page.component.ngtypecheck.ts","../../../../src/services/youtube-api.service.ngtypecheck.ts","../../../../src/models/video.model.ngtypecheck.ts","../../../../src/models/video.model.ts","../../../../src/services/youtube-api.service.ts","../../../../src/components/themes/theme-page.component.ts","../../../../src/components/shared/infinite-anchor/infinite-anchor.component.ngtypecheck.ts","../../../../src/components/shared/infinite-anchor/infinite-anchor.component.ts","../../../../src/components/themes/provider-theme-page.component.ngtypecheck.ts","../../../../src/components/themes/provider-theme-page.component.ts","../../../../src/components/search/search.component.ngtypecheck.ts","../../../../src/utils/date.util.ngtypecheck.ts","../../../../src/utils/date.util.ts","../../../../src/components/search/search.component.ts","../../../../src/components/shorts/watch-short.component.ngtypecheck.ts","../../../../src/components/shorts/watch-short.component.ts","../../../../src/components/video-player/video-player.component.ngtypecheck.ts","../../../../src/components/video-player/video-player.component.ts","../../../../src/components/watch/watch.component.ngtypecheck.ts","../../../../src/services/gemini.service.ngtypecheck.ts","../../../../node_modules/zod/v3/helpers/typealiases.d.cts","../../../../node_modules/zod/v3/helpers/util.d.cts","../../../../node_modules/zod/v3/index.d.cts","../../../../node_modules/zod/v3/zoderror.d.cts","../../../../node_modules/zod/v3/locales/en.d.cts","../../../../node_modules/zod/v3/errors.d.cts","../../../../node_modules/zod/v3/helpers/parseutil.d.cts","../../../../node_modules/zod/v3/helpers/enumutil.d.cts","../../../../node_modules/zod/v3/helpers/errorutil.d.cts","../../../../node_modules/zod/v3/helpers/partialutil.d.cts","../../../../node_modules/zod/v3/standard-schema.d.cts","../../../../node_modules/zod/v3/types.d.cts","../../../../node_modules/zod/v3/external.d.cts","../../../../node_modules/zod/index.d.cts","../../../../node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/types.d.ts","../../../../node_modules/@modelcontextprotocol/sdk/dist/esm/types.d.ts","../../../../node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.d.ts","../../../../node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.d.ts","../../../../node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.d.ts","../../../../node_modules/gaxios/build/src/common.d.ts","../../../../node_modules/gaxios/build/src/interceptor.d.ts","../../../../node_modules/gaxios/build/src/gaxios.d.ts","../../../../node_modules/gaxios/build/src/index.d.ts","../../../../node_modules/google-auth-library/build/src/transporters.d.ts","../../../../node_modules/google-auth-library/build/src/auth/credentials.d.ts","../../../../node_modules/google-auth-library/build/src/crypto/crypto.d.ts","../../../../node_modules/google-auth-library/build/src/util.d.ts","../../../../node_modules/google-auth-library/build/src/auth/authclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/loginticket.d.ts","../../../../node_modules/google-auth-library/build/src/auth/oauth2client.d.ts","../../../../node_modules/google-auth-library/build/src/auth/idtokenclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/envdetect.d.ts","../../../../node_modules/gtoken/build/src/index.d.ts","../../../../node_modules/google-auth-library/build/src/auth/jwtclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/refreshclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/impersonated.d.ts","../../../../node_modules/google-auth-library/build/src/auth/baseexternalclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/identitypoolclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/awsrequestsigner.d.ts","../../../../node_modules/google-auth-library/build/src/auth/awsclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/pluggable-auth-client.d.ts","../../../../node_modules/google-auth-library/build/src/auth/externalclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/externalaccountauthorizeduserclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/googleauth.d.ts","../../../../node_modules/gcp-metadata/build/src/gcp-residency.d.ts","../../../../node_modules/gcp-metadata/build/src/index.d.ts","../../../../node_modules/google-auth-library/build/src/auth/computeclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/iam.d.ts","../../../../node_modules/google-auth-library/build/src/auth/jwtaccess.d.ts","../../../../node_modules/google-auth-library/build/src/auth/downscopedclient.d.ts","../../../../node_modules/google-auth-library/build/src/auth/passthrough.d.ts","../../../../node_modules/google-auth-library/build/src/index.d.ts","../../../../node_modules/@google/genai/dist/genai.d.ts","../../../../src/services/gemini.service.ts","../../../../src/services/download.service.ngtypecheck.ts","../../../../src/services/download.service.ts","../../../../src/components/watch/watch.component.ts","../../../../src/components/library/playlists/playlists.component.ngtypecheck.ts","../../../../src/components/library/playlists/playlists.component.ts","../../../../src/components/library/liked/liked.component.ngtypecheck.ts","../../../../src/components/library/liked/liked.component.ts","../../../../src/components/library/subscriptions/subscriptions.component.ngtypecheck.ts","../../../../src/components/library/subscriptions/subscriptions.component.ts","../../../../src/components/account/preferences/preferences.component.ngtypecheck.ts","../../../../src/components/account/preferences/preferences.component.ts","../../../../src/components/account/history/history.component.ngtypecheck.ts","../../../../src/components/account/history/history.component.ts","../../../../src/components/account/sessions/sessions.component.ngtypecheck.ts","../../../../src/components/account/sessions/sessions.component.ts","../../../../src/components/auth/login/login.component.ngtypecheck.ts","../../../../src/components/auth/login/login.component.ts","../../../../src/components/auth/register/register.component.ngtypecheck.ts","../../../../src/components/auth/register/register.component.ts","../../../../src/components/info/utilisation/utilisation.component.ngtypecheck.ts","../../../../src/components/info/utilisation/utilisation.component.ts","../../../../src/app.routes.ts","../../../../src/interceptors/auth.interceptor.ngtypecheck.ts","../../../../src/interceptors/auth.interceptor.ts","../../../../index.tsx","../../../../src/components/home/home.component.ngtypecheck.ts","../../../../src/components/home/home.component.ts","../../../../node_modules/@types/estree/index.d.ts","../../../../node_modules/@types/node/compatibility/disposable.d.ts","../../../../node_modules/@types/node/compatibility/indexable.d.ts","../../../../node_modules/@types/node/compatibility/iterators.d.ts","../../../../node_modules/@types/node/compatibility/index.d.ts","../../../../node_modules/@types/node/globals.typedarray.d.ts","../../../../node_modules/@types/node/buffer.buffer.d.ts","../../../../node_modules/@types/node/globals.d.ts","../../../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../../../node_modules/@types/node/web-globals/domexception.d.ts","../../../../node_modules/@types/node/web-globals/events.d.ts","../../../../node_modules/buffer/index.d.ts","../../../../node_modules/undici-types/header.d.ts","../../../../node_modules/undici-types/readable.d.ts","../../../../node_modules/undici-types/file.d.ts","../../../../node_modules/undici-types/fetch.d.ts","../../../../node_modules/undici-types/formdata.d.ts","../../../../node_modules/undici-types/connector.d.ts","../../../../node_modules/undici-types/client.d.ts","../../../../node_modules/undici-types/errors.d.ts","../../../../node_modules/undici-types/dispatcher.d.ts","../../../../node_modules/undici-types/global-dispatcher.d.ts","../../../../node_modules/undici-types/global-origin.d.ts","../../../../node_modules/undici-types/pool-stats.d.ts","../../../../node_modules/undici-types/pool.d.ts","../../../../node_modules/undici-types/handlers.d.ts","../../../../node_modules/undici-types/balanced-pool.d.ts","../../../../node_modules/undici-types/agent.d.ts","../../../../node_modules/undici-types/mock-interceptor.d.ts","../../../../node_modules/undici-types/mock-agent.d.ts","../../../../node_modules/undici-types/mock-client.d.ts","../../../../node_modules/undici-types/mock-pool.d.ts","../../../../node_modules/undici-types/mock-errors.d.ts","../../../../node_modules/undici-types/proxy-agent.d.ts","../../../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../../../node_modules/undici-types/retry-handler.d.ts","../../../../node_modules/undici-types/retry-agent.d.ts","../../../../node_modules/undici-types/api.d.ts","../../../../node_modules/undici-types/interceptors.d.ts","../../../../node_modules/undici-types/util.d.ts","../../../../node_modules/undici-types/cookies.d.ts","../../../../node_modules/undici-types/patch.d.ts","../../../../node_modules/undici-types/websocket.d.ts","../../../../node_modules/undici-types/eventsource.d.ts","../../../../node_modules/undici-types/filereader.d.ts","../../../../node_modules/undici-types/diagnostics-channel.d.ts","../../../../node_modules/undici-types/content-type.d.ts","../../../../node_modules/undici-types/cache.d.ts","../../../../node_modules/undici-types/index.d.ts","../../../../node_modules/@types/node/web-globals/fetch.d.ts","../../../../node_modules/@types/node/web-globals/navigator.d.ts","../../../../node_modules/@types/node/web-globals/storage.d.ts","../../../../node_modules/@types/node/assert.d.ts","../../../../node_modules/@types/node/assert/strict.d.ts","../../../../node_modules/@types/node/async_hooks.d.ts","../../../../node_modules/@types/node/buffer.d.ts","../../../../node_modules/@types/node/child_process.d.ts","../../../../node_modules/@types/node/cluster.d.ts","../../../../node_modules/@types/node/console.d.ts","../../../../node_modules/@types/node/constants.d.ts","../../../../node_modules/@types/node/crypto.d.ts","../../../../node_modules/@types/node/dgram.d.ts","../../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../../node_modules/@types/node/dns.d.ts","../../../../node_modules/@types/node/dns/promises.d.ts","../../../../node_modules/@types/node/domain.d.ts","../../../../node_modules/@types/node/events.d.ts","../../../../node_modules/@types/node/fs.d.ts","../../../../node_modules/@types/node/fs/promises.d.ts","../../../../node_modules/@types/node/http.d.ts","../../../../node_modules/@types/node/http2.d.ts","../../../../node_modules/@types/node/https.d.ts","../../../../node_modules/@types/node/inspector.d.ts","../../../../node_modules/@types/node/module.d.ts","../../../../node_modules/@types/node/net.d.ts","../../../../node_modules/@types/node/os.d.ts","../../../../node_modules/@types/node/path.d.ts","../../../../node_modules/@types/node/perf_hooks.d.ts","../../../../node_modules/@types/node/process.d.ts","../../../../node_modules/@types/node/punycode.d.ts","../../../../node_modules/@types/node/querystring.d.ts","../../../../node_modules/@types/node/readline.d.ts","../../../../node_modules/@types/node/readline/promises.d.ts","../../../../node_modules/@types/node/repl.d.ts","../../../../node_modules/@types/node/sea.d.ts","../../../../node_modules/@types/node/sqlite.d.ts","../../../../node_modules/@types/node/stream.d.ts","../../../../node_modules/@types/node/stream/promises.d.ts","../../../../node_modules/@types/node/stream/consumers.d.ts","../../../../node_modules/@types/node/stream/web.d.ts","../../../../node_modules/@types/node/string_decoder.d.ts","../../../../node_modules/@types/node/test.d.ts","../../../../node_modules/@types/node/timers.d.ts","../../../../node_modules/@types/node/timers/promises.d.ts","../../../../node_modules/@types/node/tls.d.ts","../../../../node_modules/@types/node/trace_events.d.ts","../../../../node_modules/@types/node/tty.d.ts","../../../../node_modules/@types/node/url.d.ts","../../../../node_modules/@types/node/util.d.ts","../../../../node_modules/@types/node/v8.d.ts","../../../../node_modules/@types/node/vm.d.ts","../../../../node_modules/@types/node/wasi.d.ts","../../../../node_modules/@types/node/worker_threads.d.ts","../../../../node_modules/@types/node/zlib.d.ts","../../../../node_modules/@types/node/index.d.ts"],"fileIdsList":[[59,402,451],[59,60,252,258,265,266,268,276,278,280,293,390,392,402,451],[252,258,259,402,451],[252,258,261,264,402,451],[252,258,259,260,261,402,451],[258,402,451],[402,451],[63,402,451],[61,62,402,451],[61,62,63,252,253,254,402,451],[61,402,451],[61,62,63,252,253,254,255,256,257,402,451],[252,258,402,451],[258,262,402,451],[258,262,263,265,402,451],[252,258,262,266,267,402,451],[252,258,262,402,451],[333,366,402,451],[328,330,331,332,402,451],[328,329,330,331,402,451],[330,402,451],[328,329,402,451],[402,448,451],[402,450,451],[451],[402,451,456,485],[402,451,452,457,462,470,482,493],[402,451,452,453,462,470],[397,398,399,402,451],[402,451,454,494],[402,451,455,456,463,471],[402,451,456,482,490],[402,451,457,459,462,470],[402,450,451,458],[402,451,459,460],[402,451,461,462],[402,450,451,462],[402,451,462,463,464,482,493],[402,451,462,463,464,477,482,485],[402,444,451,459,462,465,470,482,493],[402,451,462,463,465,466,470,482,490,493],[402,451,465,467,482,490,493],[400,401,402,403,404,405,406,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499],[402,451,462,468],[402,451,469,493],[402,451,459,462,470,482],[402,451,471],[402,451,472],[402,450,451,473],[402,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499],[402,451,475],[402,451,476],[402,451,462,477,478],[402,451,477,479,494,496],[402,451,462,482,483,485],[402,451,484,485],[402,451,482,483],[402,451,485],[402,451,486],[402,448,451,482,487],[402,451,462,488,489],[402,451,488,489],[402,451,456,470,482,490],[402,451,491],[402,451,470,492],[402,451,465,476,493],[402,451,456,494],[402,451,482,495],[402,451,469,496],[402,451,497],[402,444,451],[402,451,462,464,473,482,485,493,495,496,498],[402,451,482,499],[402,451,465,482,493],[334,335,402,451,465,493],[334,335,336,402,451],[334,402,451],[359,402,451,465],[337,338,339,341,344,402,451,462],[341,342,351,353,402,451],[337,402,451],[337,338,339,341,342,344,402,451],[337,344,402,451],[337,338,339,342,344,402,451],[337,338,339,342,344,351,402,451],[342,351,352,354,355,402,451],[337,338,339,342,344,345,346,348,349,350,351,356,357,366,402,451,482],[341,342,351,402,451],[344,402,451],[342,344,345,358,402,451],[339,344,402,451,482],[339,344,345,347,402,451,482],[337,338,339,340,342,343,402,451,476],[337,342,344,402,451],[342,351,402,451],[337,338,339,342,343,344,345,346,348,349,350,351,352,353,354,355,356,358,360,361,362,363,364,365,366,402,451],[64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,80,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,120,121,122,123,124,125,126,127,128,129,130,131,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,183,184,185,187,196,198,199,200,201,202,203,205,206,208,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,402,451],[109,402,451],[65,68,402,451],[67,402,451],[67,68,402,451],[64,65,66,68,402,451],[65,67,68,225,402,451],[68,402,451],[64,67,109,402,451],[67,68,225,402,451],[67,233,402,451],[65,67,68,402,451],[77,402,451],[100,402,451],[121,402,451],[67,68,109,402,451],[68,116,402,451],[67,68,109,127,402,451],[67,68,127,402,451],[68,168,402,451],[68,109,402,451],[64,68,186,402,451],[64,68,187,402,451],[209,402,451],[193,195,402,451],[204,402,451],[193,402,451],[64,68,186,193,194,402,451],[186,187,195,402,451],[207,402,451],[64,68,193,194,195,402,451],[66,67,68,402,451],[64,68,402,451],[65,67,187,188,189,190,402,451],[109,187,188,189,190,402,451],[187,189,402,451],[67,188,189,191,192,196,402,451],[64,67,402,451],[68,211,402,451],[69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,110,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,402,451],[197,402,451],[402,416,420,451,493],[402,416,451,482,493],[402,411,451],[402,413,416,451,490,493],[402,451,470,490],[402,451,500],[402,411,451,500],[402,413,416,451,470,493],[402,408,409,412,415,451,462,482,493],[402,416,423,451],[402,408,414,451],[402,416,437,438,451],[402,412,416,451,485,493,500],[402,437,451,500],[402,410,411,451,500],[402,416,451],[402,410,411,412,413,414,415,416,417,418,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,438,439,440,441,442,443,451],[402,416,431,451],[402,416,423,424,451],[402,414,416,424,425,451],[402,415,451],[402,408,411,416,451],[402,416,420,424,425,451],[402,420,451],[402,414,416,419,451,493],[402,408,413,416,423,451],[402,451,482],[402,411,416,437,451,498,500],[327,402,451],[318,319,402,451],[315,316,318,320,321,326,402,451],[316,318,402,451],[326,402,451],[318,402,451],[315,316,318,321,322,323,324,325,402,451],[315,316,317,402,451],[59,258,287,289,293,402,451],[59,258,268,271,287,289,290,292,402,451],[59,268,294,300,304,308,310,371,373,375,377,379,381,383,385,387,389,402,451],[59,258,262,268,381,402,451],[59,258,262,268,286,380,402,451],[59,258,262,272,273,379,402,451],[59,252,258,262,271,272,273,276,280,378,402,451],[59,258,262,383,402,451],[59,252,258,262,278,382,402,451],[59,258,262,268,273,385,402,451],[59,252,258,262,268,273,276,278,280,384,402,451],[59,258,262,268,273,387,402,451],[59,252,258,262,268,273,276,278,280,386,402,451],[59,258,262,268,272,273,287,402,451],[59,252,258,262,268,271,272,273,274,276,278,280,284,286,402,451],[59,258,262,268,272,302,395,402,451],[59,258,262,268,272,276,298,299,302,307,394,402,451],[59,258,389,402,451],[59,258,262,388,402,451],[59,258,375,402,451],[59,258,262,374,402,451],[59,258,373,402,451],[59,258,262,372,402,451],[59,258,377,402,451],[59,258,262,376,402,451],[59,258,262,268,272,302,308,402,451],[59,258,262,266,268,272,276,286,298,299,302,305,307,402,451],[59,258,302,402,451],[59,258,262,301,402,451],[59,258,310,402,451],[59,252,258,262,266,276,298,299,309,402,451],[59,258,262,268,272,289,402,451],[59,258,262,268,272,276,284,288,402,451],[59,258,262,268,272,273,302,304,402,451],[59,258,262,268,272,273,276,284,298,299,302,303,402,451],[59,258,262,268,272,300,402,451],[59,258,262,268,272,276,284,295,298,299,402,451],[59,258,262,292,402,451],[59,258,262,268,284,291,402,451],[59,258,312,402,451],[59,258,311,402,451],[59,258,268,312,371,402,451],[59,252,258,262,265,266,268,276,278,286,298,299,307,312,313,368,370,402,451],[59,185,252,258,265,278,391,402,451],[59,282,402,451],[59,297,402,451],[59,258,269,271,402,451],[59,185,252,258,265,277,402,451],[59,252,258,265,369,402,451],[59,258,314,367,402,451],[59,252,258,265,285,402,451],[59,258,270,402,451],[59,258,275,402,451],[59,258,271,281,283,402,451],[59,185,252,258,265,278,279,402,451],[59,185,252,258,265,271,276,296,298,402,451],[59,306,402,451]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"b5ce7a470bc3628408429040c4e3a53a27755022a32fd05e2cb694e7015386c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6a5253138c5432c68a1510c70fe78a644fe2e632111ba778e1978010d6edfec","impliedFormat":1},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"d9d3dd93b80c648c9d33766a515f43cceeea16a1240887d53c6ec4fd9a4c0687","impliedFormat":99},{"version":"8b112cd3d8d6fa2449e7cef7643660adbd5c05212f82cf6add0090e0e889b145","affectsGlobalScope":true,"impliedFormat":99},{"version":"31151a7a97f8e16f57099be0cedb8fae67cfbeaa56dad030358709b7672d32c8","affectsGlobalScope":true,"impliedFormat":99},{"version":"073ca26c96184db9941b5ec0ddea6981c9b816156d9095747809e524fdd90e35","impliedFormat":1},{"version":"e41d17a2ec23306d953cda34e573ed62954ca6ea9b8c8b74e013d07a6886ce47","impliedFormat":1},{"version":"241bd4add06f06f0699dcd58f3b334718d85e3045d9e9d4fa556f11f4d1569c1","impliedFormat":1},{"version":"2ae3787e1498b20aad1b9c2ee9ea517ec30e89b70d242d8e3e52d1e091039695","impliedFormat":1},{"version":"c7c72c4cffb1bc83617eefed71ed68cc89df73cab9e19507ccdecb3e72b4967e","affectsGlobalScope":true,"impliedFormat":1},{"version":"b8bff8a60af0173430b18d9c3e5c443eaa3c515617210c0c7b3d2e1743c19ecb","impliedFormat":1},{"version":"38b38db08e7121828294dec10957a7a9ff263e33e2a904b346516d4a4acca482","impliedFormat":1},{"version":"a76ebdf2579e68e4cfe618269c47e5a12a4e045c2805ed7f7ab37af8daa6b091","impliedFormat":1},{"version":"8a2aaea564939c22be05d665cc955996721bad6d43148f8fa21ae8f64afecd37","impliedFormat":1},{"version":"e59d36b7b6e8ba2dd36d032a5f5c279d2460968c8b4e691ca384f118fb09b52a","impliedFormat":1},{"version":"e96885c0684c9042ec72a9a43ef977f6b4b4a2728f4b9e737edcbaa0c74e5bf6","impliedFormat":1},{"version":"95950a187596e206d32d5d9c7b932901088c65ed8f9040e614aa8e321e0225ef","impliedFormat":1},{"version":"89e061244da3fc21b7330f4bd32f47c1813dd4d7f1dc3d0883d88943f035b993","impliedFormat":1},{"version":"e46558c2e04d06207b080138678020448e7fc201f3d69c2601b0d1456105f29a","impliedFormat":1},{"version":"71549375db52b1163411dba383b5f4618bdf35dc57fa327a1c7d135cf9bf67d1","impliedFormat":1},{"version":"7e6b2d61d6215a4e82ea75bc31a80ebb8ad0c2b37a60c10c70dd671e8d9d6d5d","impliedFormat":1},{"version":"78bea05df2896083cca28ed75784dde46d4b194984e8fc559123b56873580a23","impliedFormat":1},{"version":"5dd04ced37b7ea09f29d277db11f160df7fd73ba8b9dba86cb25552e0653a637","impliedFormat":1},{"version":"f74b81712e06605677ae1f061600201c425430151f95b5ef4d04387ad7617e6a","impliedFormat":1},{"version":"9a72847fcf4ac937e352d40810f7b7aec7422d9178451148296cf1aa19467620","impliedFormat":1},{"version":"3ae18f60e0b96fa1e025059b7d25b3247ba4dcb5f4372f6d6e67ce2adac74eac","impliedFormat":1},{"version":"2b9260f44a2e071450ae82c110f5dc8f330c9e5c3e85567ed97248330f2bf639","impliedFormat":1},{"version":"4f196e13684186bda6f5115fc4677a87cf84a0c9c4fc17b8f51e0984f3697b6d","impliedFormat":1},{"version":"61419f2c5822b28c1ea483258437c1faab87d00c6f84481aa22afb3380d8e9a4","impliedFormat":1},{"version":"64479aee03812264e421c0bf5104a953ca7b02740ba80090aead1330d0effe91","impliedFormat":1},{"version":"0521108c9f8ddb17654a0a54dae6ba9667c99eddccfd6af5748113e022d1c37a","impliedFormat":1},{"version":"c5570e504be103e255d80c60b56c367bf45d502ca52ee35c55dec882f6563b5c","impliedFormat":1},{"version":"ee764e6e9a7f2b987cc1a2c0a9afd7a8f4d5ebc4fdb66ad557a7f14a8c2bd320","impliedFormat":1},{"version":"0520b5093712c10c6ef23b5fea2f833bf5481771977112500045e5ea7e8e2b69","impliedFormat":1},{"version":"5c3cf26654cf762ac4d7fd7b83f09acfe08eef88d2d6983b9a5a423cb4004ca3","impliedFormat":1},{"version":"e60fa19cf7911c1623b891155d7eb6b7e844e9afdf5738e3b46f3b687730a2bd","impliedFormat":1},{"version":"b1fd72ff2bb0ba91bb588f3e5329f8fc884eb859794f1c4657a2bfa122ae54d0","impliedFormat":1},{"version":"6cf42a4f3cfec648545925d43afaa8bb364ac10a839ffed88249da109361b275","impliedFormat":1},{"version":"d7058e75920120b142a9d57be25562a3cd9a936269fd52908505f530105f2ec4","impliedFormat":1},{"version":"6df52b70d7f7702202f672541a5f4a424d478ee5be51a9d37b8ccbe1dbf3c0f2","impliedFormat":1},{"version":"0ca7f997e9a4d8985e842b7c882e521b6f63233c4086e9fe79dd7a9dc4742b5e","impliedFormat":1},{"version":"91046b5c6b55d3b194c81fd4df52f687736fad3095e9d103ead92bb64dc160ee","impliedFormat":1},{"version":"db5704fdad56c74dfc5941283c1182ed471bd17598209d3ac4a49faa72e43cfc","impliedFormat":1},{"version":"758e8e89559b02b81bc0f8fd395b17ad5aff75490c862cbe369bb1a3d1577c40","impliedFormat":1},{"version":"2ee64342c077b1868f1834c063f575063051edd6e2964257d34aad032d6b657c","impliedFormat":1},{"version":"6f6b4b3d670b6a5f0e24ea001c1b3d36453c539195e875687950a178f1730fa7","impliedFormat":1},{"version":"a472a1d3f25ce13a1d44911cd3983956ac040ce2018e155435ea34afb25f864c","impliedFormat":1},{"version":"b48b83a86dd9cfe36f8776b3ff52fcd45b0e043c0538dc4a4b149ba45fe367b9","impliedFormat":1},{"version":"792de5c062444bd2ee0413fb766e57e03cce7cdaebbfc52fc0c7c8e95069c96b","impliedFormat":1},{"version":"a79e3e81094c7a04a885bad9b049c519aace53300fb8a0fe4f26727cb5a746ce","impliedFormat":1},{"version":"93181bac0d90db185bb730c95214f6118ae997fe836a98a49664147fbcaf1988","impliedFormat":1},{"version":"8a4e89564d8ea66ad87ee3762e07540f9f0656a62043c910d819b4746fc429c5","impliedFormat":1},{"version":"b9011d99942889a0f95e120d06b698c628b0b6fdc3e6b7ecb459b97ed7d5bcc6","impliedFormat":1},{"version":"4d639cbbcc2f8f9ce6d55d5d503830d6c2556251df332dc5255d75af53c8a0e7","impliedFormat":1},{"version":"cdb48277f600ab5f429ecf1c5ea046683bc6b9f73f3deab9a100adac4b34969c","impliedFormat":1},{"version":"75be84956a29040a1afbe864c0a7a369dfdb739380072484eff153905ef867ee","impliedFormat":1},{"version":"b06b4adc2ae03331a92abd1b19af8eb91ec2bf8541747ee355887a167d53145e","impliedFormat":1},{"version":"c54166a85bd60f86d1ebb90ce0117c0ecb850b8a33b366691629fdf26f1bbbd8","impliedFormat":1},{"version":"0d417c15c5c635384d5f1819cc253a540fe786cc3fda32f6a2ae266671506a21","impliedFormat":1},{"version":"80f23f1d60fbed356f726b3b26f9d348dddbb34027926d10d59fad961e70a730","impliedFormat":1},{"version":"cb59317243a11379a101eb2f27b9df1022674c3df1df0727360a0a3f963f523b","impliedFormat":1},{"version":"cc20bb2227dd5de0aab0c8d697d1572f8000550e62c7bf5c92f212f657dd88c5","impliedFormat":1},{"version":"06b8a7d46195b6b3980e523ef59746702fd210b71681a83a5cf73799623621f9","impliedFormat":1},{"version":"860e4405959f646c101b8005a191298b2381af8f33716dc5f42097e4620608f8","impliedFormat":1},{"version":"f7e32adf714b8f25d3c1783473abec3f2e82d5724538d8dcf6f51baaaff1ca7a","impliedFormat":1},{"version":"d0da80c845999a16c24d0783033fb5366ada98df17867c98ad433ede05cd87fd","impliedFormat":1},{"version":"bfbf80f9cd4558af2d7b2006065340aaaced15947d590045253ded50aabb9bc5","impliedFormat":1},{"version":"fd9a991b51870325e46ebb0e6e18722d313f60cd8e596e645ec5ac15b96dbf4e","impliedFormat":1},{"version":"c3bd2b94e4298f81743d92945b80e9b56c1cdfb2bef43c149b7106a2491b1fc9","impliedFormat":1},{"version":"a246cce57f558f9ebaffd55c1e5673da44ea603b4da3b2b47eb88915d30a9181","impliedFormat":1},{"version":"d993eacc103c5a065227153c9aae8acea3a4322fe1a169ee7c70b77015bf0bb2","impliedFormat":1},{"version":"fc2b03d0c042aa1627406e753a26a1eaad01b3c496510a78016822ef8d456bb6","impliedFormat":1},{"version":"063c7ebbe756f0155a8b453f410ca6b76ffa1bbc1048735bcaf9c7c81a1ce35f","impliedFormat":1},{"version":"314e402cd481370d08f63051ae8b8c8e6370db5ee3b8820eeeaaf8d722a6dac6","impliedFormat":1},{"version":"9669075ac38ce36b638b290ba468233980d9f38bdc62f0519213b2fd3e2552ec","impliedFormat":1},{"version":"4d123de012c24e2f373925100be73d50517ac490f9ed3578ac82d0168bfbd303","impliedFormat":1},{"version":"656c9af789629aa36b39092bee3757034009620439d9a39912f587538033ce28","impliedFormat":1},{"version":"3ac3f4bdb8c0905d4c3035d6f7fb20118c21e8a17bee46d3735195b0c2a9f39f","impliedFormat":1},{"version":"1f453e6798ed29c86f703e9b41662640d4f2e61337007f27ac1c616f20093f69","impliedFormat":1},{"version":"af43b7871ff21c62bf1a54ec5c488e31a8d3408d5b51ff2e9f8581b6c55f2fc7","impliedFormat":1},{"version":"70550511d25cbb0b6a64dcac7fffc3c1397fd4cbeb6b23ccc7f9b794ab8a6954","impliedFormat":1},{"version":"af0fbf08386603a62f2a78c42d998c90353b1f1d22e05a384545f7accf881e0a","impliedFormat":1},{"version":"cefc20054d20b85b534206dbcedd509bb74f87f3d8bc45c58c7be3a76caa45e1","impliedFormat":1},{"version":"ad6eee4877d0f7e5244d34bc5026fd6e9cf8e66c5c79416b73f9f6ebf132f924","impliedFormat":1},{"version":"4888fd2bcfee9a0ce89d0df860d233e0cee8ee9c479b6bd5a5d5f9aae98342fe","impliedFormat":1},{"version":"f4749c102ced952aa6f40f0b579865429c4869f6d83df91000e98005476bee87","impliedFormat":1},{"version":"56654d2c5923598384e71cb808fac2818ca3f07dd23bb018988a39d5e64f268b","impliedFormat":1},{"version":"8b6719d3b9e65863da5390cb26994602c10a315aa16e7d70778a63fee6c4c079","impliedFormat":1},{"version":"05f56cd4b929977d18df8f3d08a4c929a2592ef5af083e79974b20a063f30940","impliedFormat":1},{"version":"547d3c406a21b30e2b78629ecc0b2ddaf652d9e0bdb2d59ceebce5612906df33","impliedFormat":1},{"version":"b3a4f9385279443c3a5568ec914a9492b59a723386161fd5ef0619d9f8982f97","impliedFormat":1},{"version":"3fe66aba4fbe0c3ba196a4f9ed2a776fe99dc4d1567a558fb11693e9fcc4e6ed","impliedFormat":1},{"version":"140eef237c7db06fc5adcb5df434ee21e81ee3a6fd57e1a75b8b3750aa2df2d8","impliedFormat":1},{"version":"0944ec553e4744efae790c68807a461720cff9f3977d4911ac0d918a17c9dd99","impliedFormat":1},{"version":"cb46b38d5e791acaa243bf342b8b5f8491639847463ac965b93896d4fb0af0d9","impliedFormat":1},{"version":"7c7d9e116fe51100ff766703e6b5e4424f51ad8977fe474ddd8d0959aa6de257","impliedFormat":1},{"version":"af70a2567e586be0083df3938b6a6792e6821363d8ef559ad8d721a33a5bcdaf","impliedFormat":1},{"version":"006cff3a8bcb92d77953f49a94cd7d5272fef4ab488b9052ef82b6a1260d870b","impliedFormat":1},{"version":"7d44bfdc8ee5e9af70738ff652c622ae3ad81815e63ab49bdc593d34cb3a68e5","impliedFormat":1},{"version":"339814517abd4dbc7b5f013dfd3b5e37ef0ea914a8bbe65413ecffd668792bc6","impliedFormat":1},{"version":"34d5bc0a6958967ec237c99f980155b5145b76e6eb927c9ffc57d8680326b5d8","impliedFormat":1},{"version":"9eae79b70c9d8288032cbe1b21d0941f6bd4f315e14786b2c1d10bccc634e897","impliedFormat":1},{"version":"18ce015ed308ea469b13b17f99ce53bbb97975855b2a09b86c052eefa4aa013a","impliedFormat":1},{"version":"5a931bc4106194e474be141e0bc1046629510dc95b9a0e4b02a3783847222965","impliedFormat":1},{"version":"5e5f371bf23d5ced2212a5ff56675aefbd0c9b3f4d4fdda1b6123ac6e28f058c","impliedFormat":1},{"version":"907c17ad5a05eecb29b42b36cc8fec6437be27cc4986bb3a218e4f74f606911c","impliedFormat":1},{"version":"ce60a562cd2a92f37a88f2ddd99a3abfbc5848d7baf38c48fb8d3243701fcb75","impliedFormat":1},{"version":"a726ad2d0a98bfffbe8bc1cd2d90b6d831638c0adc750ce73103a471eb9a891c","impliedFormat":1},{"version":"f44c0c8ce58d3dacac016607a1a90e5342d830ea84c48d2e571408087ae55894","impliedFormat":1},{"version":"75a315a098e630e734d9bc932d9841b64b30f7a349a20cf4717bf93044eff113","impliedFormat":1},{"version":"9131d95e32b3d4611d4046a613e022637348f6cebfe68230d4e81b691e4761a1","impliedFormat":1},{"version":"b03aa292cfdcd4edc3af00a7dbd71136dd067ec70a7536b655b82f4dd444e857","impliedFormat":1},{"version":"b6e2b0448ced813b8c207810d96551a26e7d7bb73255eea4b9701698f78846d6","impliedFormat":1},{"version":"8ae10cd85c1bd94d2f2d17c4cbd25c068a4b2471c70c2d96434239f97040747a","impliedFormat":1},{"version":"9ed5b799c50467b0c9f81ddf544b6bcda3e34d92076d6cab183c84511e45c39f","impliedFormat":1},{"version":"b4fa87cc1833839e51c49f20de71230e259c15b2c9c3e89e4814acc1d1ef10de","impliedFormat":1},{"version":"e90ac9e4ac0326faa1bc39f37af38ace0f9d4a655cd6d147713c653139cf4928","impliedFormat":1},{"version":"ea27110249d12e072956473a86fd1965df8e1be985f3b686b4e277afefdde584","impliedFormat":1},{"version":"8776a368617ce51129b74db7d55c3373dadcce5d0701e61d106e99998922a239","impliedFormat":1},{"version":"5666075052877fe2fdddd5b16de03168076cf0f03fbca5c1d4a3b8f43cba570c","impliedFormat":1},{"version":"9108ab5af05418f599ab48186193b1b07034c79a4a212a7f73535903ba4ca249","impliedFormat":1},{"version":"bb4e2cdcadf9c9e6ee2820af23cee6582d47c9c9c13b0dca1baaffe01fbbcb5f","impliedFormat":1},{"version":"6e30d0b5a1441d831d19fe02300ab3d83726abd5141cbcc0e2993fa0efd33db4","impliedFormat":1},{"version":"423f28126b2fc8d8d6fa558035309000a1297ed24473c595b7dec52e5c7ebae5","impliedFormat":1},{"version":"fb30734f82083d4790775dae393cd004924ebcbfde49849d9430bf0f0229dd16","impliedFormat":1},{"version":"2c92b04a7a4a1cd9501e1be338bf435738964130fb2ad5bd6c339ee41224ac4c","impliedFormat":1},{"version":"c5c5f0157b41833180419dacfbd2bcce78fb1a51c136bd4bcba5249864d8b9b5","impliedFormat":1},{"version":"02ae43d5bae42efcd5a00d3923e764895ce056bca005a9f4e623aa6b4797c8af","impliedFormat":1},{"version":"db6e01f17012a9d7b610ae764f94a1af850f5d98c9c826ad61747dca0fb800bd","impliedFormat":1},{"version":"8a44b424edee7bb17dc35a558cc15f92555f14a0441205613e0e50452ab3a602","impliedFormat":1},{"version":"24a00d0f98b799e6f628373249ece352b328089c3383b5606214357e9107e7d5","impliedFormat":1},{"version":"33637e3bc64edd2075d4071c55d60b32bdb0d243652977c66c964021b6fc8066","impliedFormat":1},{"version":"0f0ad9f14dedfdca37260931fac1edf0f6b951c629e84027255512f06a6ebc4c","impliedFormat":1},{"version":"16ad86c48bf950f5a480dc812b64225ca4a071827d3d18ffc5ec1ae176399e36","impliedFormat":1},{"version":"8cbf55a11ff59fd2b8e39a4aa08e25c5ddce46e3af0ed71fb51610607a13c505","impliedFormat":1},{"version":"d5bc4544938741f5daf8f3a339bfbf0d880da9e89e79f44a6383aaf056fe0159","impliedFormat":1},{"version":"97f9169882d393e6f303f570168ca86b5fe9aab556e9a43672dae7e6bb8e6495","impliedFormat":1},{"version":"7c9adb3fcd7851497818120b7e151465406e711d6a596a71b807f3a17853cb58","impliedFormat":1},{"version":"6752d402f9282dd6f6317c8c048aaaac27295739a166eed27e00391b358fed9a","impliedFormat":1},{"version":"9fd7466b77020847dbc9d2165829796bf7ea00895b2520ff3752ffdcff53564b","impliedFormat":1},{"version":"fbfc12d54a4488c2eb166ed63bab0fb34413e97069af273210cf39da5280c8d6","impliedFormat":1},{"version":"85a84240002b7cf577cec637167f0383409d086e3c4443852ca248fc6e16711e","impliedFormat":1},{"version":"84794e3abd045880e0fadcf062b648faf982aa80cfc56d28d80120e298178626","impliedFormat":1},{"version":"053d8b827286a16a669a36ffc8ccc8acdf8cc154c096610aa12348b8c493c7b8","impliedFormat":1},{"version":"3cce4ce031710970fe12d4f7834375f5fd455aa129af4c11eb787935923ff551","impliedFormat":1},{"version":"8f62cbd3afbd6a07bb8c934294b6bfbe437021b89e53a4da7de2648ecfc7af25","impliedFormat":1},{"version":"62c3621d34fb2567c17a2c4b89914ebefbfbd1b1b875b070391a7d4f722e55dc","impliedFormat":1},{"version":"c05ac811542e0b59cb9c2e8f60e983461f0b0e39cea93e320fad447ff8e474f3","impliedFormat":1},{"version":"8e7a5b8f867b99cc8763c0b024068fb58e09f7da2c4810c12833e1ca6eb11c4f","impliedFormat":1},{"version":"132351cbd8437a463757d3510258d0fa98fd3ebef336f56d6f359cf3e177a3ce","impliedFormat":1},{"version":"df877050b04c29b9f8409aa10278d586825f511f0841d1ec41b6554f8362092b","impliedFormat":1},{"version":"33d1888c3c27d3180b7fd20bac84e97ecad94b49830d5dd306f9e770213027d1","impliedFormat":1},{"version":"ee942c58036a0de88505ffd7c129f86125b783888288c2389330168677d6347f","impliedFormat":1},{"version":"a3f317d500c30ea56d41501632cdcc376dae6d24770563a5e59c039e1c2a08ec","impliedFormat":1},{"version":"eb21ddc3a8136a12e69176531197def71dc28ffaf357b74d4bf83407bd845991","impliedFormat":1},{"version":"0c1651a159995dfa784c57b4ea9944f16bdf8d924ed2d8b3db5c25d25749a343","impliedFormat":1},{"version":"aaa13958e03409d72e179b5d7f6ec5c6cc666b7be14773ae7b6b5ee4921e52db","impliedFormat":1},{"version":"0a86e049843ad02977a94bb9cdfec287a6c5a0a4b6b5391a6648b1a122072c5a","impliedFormat":1},{"version":"40f06693e2e3e58526b713c937895c02e113552dc8ba81ecd49cdd9596567ddb","impliedFormat":1},{"version":"4ed5e1992aedb174fb8f5aa8796aa6d4dcb8bd819b4af1b162a222b680a37fa0","impliedFormat":1},{"version":"d7f4bd46a8b97232ea6f8c28012b8d2b995e55e729d11405f159d3e00c51420a","impliedFormat":1},{"version":"d604d413aff031f4bfbdae1560e54ebf503d374464d76d50a2c6ded4df525712","impliedFormat":1},{"version":"e4f4f9cf1e3ac9fd91ada072e4d428ecbf0aa6dc57138fb797b8a0ca3a1d521c","impliedFormat":1},{"version":"12bfd290936824373edda13f48a4094adee93239b9a73432db603127881a300d","impliedFormat":1},{"version":"340ceb3ea308f8e98264988a663640e567c553b8d6dc7d5e43a8f3b64f780374","impliedFormat":1},{"version":"c5a769564e530fba3ec696d0a5cff1709b9095a0bdf5b0826d940d2fc9786413","impliedFormat":1},{"version":"7124ef724c3fc833a17896f2d994c368230a8d4b235baed39aa8037db31de54f","impliedFormat":1},{"version":"5de1c0759a76e7710f76899dcae601386424eab11fb2efaf190f2b0f09c3d3d3","impliedFormat":1},{"version":"9c5ee8f7e581f045b6be979f062a61bf076d362bf89c7f966b993a23424e8b0d","impliedFormat":1},{"version":"1a11df987948a86aa1ec4867907c59bdf431f13ed2270444bf47f788a5c7f92d","impliedFormat":1},{"version":"8018dd2e95e7ce6e613ddd81672a54532614dc745520a2f9e3860ff7fb1be0ca","impliedFormat":1},{"version":"b756781cd40d465da57d1fc6a442c34ae61fe8c802d752aace24f6a43fedacee","impliedFormat":1},{"version":"0fe76167c87289ea094e01616dcbab795c11b56bad23e1ef8aba9aa37e93432a","impliedFormat":1},{"version":"3a45029dba46b1f091e8dc4d784e7be970e209cd7d4ff02bd15270a98a9ba24b","impliedFormat":1},{"version":"032c1581f921f8874cf42966f27fd04afcabbb7878fa708a8251cac5415a2a06","impliedFormat":1},{"version":"69c68ed9652842ce4b8e495d63d2cd425862104c9fb7661f72e7aa8a9ef836f8","impliedFormat":1},{"version":"0e704ee6e9fd8b6a5a7167886f4d8915f4bc22ed79f19cb7b32bd28458f50643","impliedFormat":1},{"version":"06f62a14599a68bcde148d1efd60c2e52e8fa540cc7dcfa4477af132bb3de271","impliedFormat":1},{"version":"904a96f84b1bcee9a7f0f258d17f8692e6652a0390566515fe6741a5c6db8c1c","impliedFormat":1},{"version":"11f19ce32d21222419cecab448fa335017ebebf4f9e5457c4fa9df42fa2dcca7","impliedFormat":1},{"version":"2e8ee2cbb5e9159764e2189cf5547aebd0e6b0d9a64d479397bb051cd1991744","impliedFormat":1},{"version":"1b0471d75f5adb7f545c1a97c02a0f825851b95fe6e069ac6ecaa461b8bb321d","impliedFormat":1},{"version":"1d157c31a02b1e5cca9bc495b3d8d39f4b42b409da79f863fb953fbe3c7d4884","impliedFormat":1},{"version":"07baaceaec03d88a4b78cb0651b25f1ae0322ac1aa0b555ae3749a79a41cba86","impliedFormat":1},{"version":"619a132f634b4ebe5b4b4179ea5870f62f2cb09916a25957bff17b408de8b56d","impliedFormat":1},{"version":"f60fa446a397eb1aead9c4e568faf2df8068b4d0306ebc075fb4be16ed26b741","impliedFormat":1},{"version":"f3cb784be4d9e91f966a0b5052a098d9b53b0af0d341f690585b0cc05c6ca412","impliedFormat":1},{"version":"350f63439f8fe2e06c97368ddc7fb6d6c676d54f59520966f7dbbe6a4586014e","impliedFormat":1},{"version":"eba613b9b357ac8c50a925fa31dc7e65ff3b95a07efbaa684b624f143d8d34ba","impliedFormat":1},{"version":"45b74185005ed45bec3f07cac6e4d68eaf02ead9ff5a66721679fb28020e5e7c","impliedFormat":1},{"version":"0f6199602df09bdb12b95b5434f5d7474b1490d2cd8cc036364ab3ba6fd24263","impliedFormat":1},{"version":"c8ca7fd9ec7a3ec82185bfc8213e4a7f63ae748fd6fced931741d23ef4ea3c0f","impliedFormat":1},{"version":"5c6a8a3c2a8d059f0592d4eab59b062210a1c871117968b10797dee36d991ef7","impliedFormat":1},{"version":"ad77fd25ece8e09247040826a777dc181f974d28257c9cd5acb4921b51967bd8","impliedFormat":1},{"version":"e636bc88ba9f36fd2e0ea4e92d998faf9ef26c3e7d3ea30363ca74e48ccae9b6","impliedFormat":99},{"version":"53a7e8e6cd478d365dab32dbf5e3f45e1fdce303f9b3843c0347722b19714449","impliedFormat":99},{"version":"0c02c17cf4c2a113c1f2c84600c584988a85d4808271ad8c38e47d1cfbb0175d","impliedFormat":99},{"version":"aad5b7d6c39fb451c626fc26aed53d713cbf1598bfb81e7555a3802d262779ae","impliedFormat":99},{"version":"63a8dadf7e342e253bc606c5f0d3f19be90352bccb6798728d928ed618fc5521","impliedFormat":99},{"version":"f37fcb53b8f0a80340d25f4ca4e1f43ababf1711d1da680fba3b62669e8198d9","impliedFormat":99},{"version":"7b725602c44d308cc120244986665583e2a53d20b69b0e4c19034609314e4960","impliedFormat":99},{"version":"bc84a8c0f0d7246cd48c745919fd87f2dcbea0894e5d9f4004b4878c8b37d5da","impliedFormat":99},{"version":"adcf6fb0fc8d31e1fd7c0477c517a2691e2f1fc20361ef2a4c4e05555b598a18","impliedFormat":99},{"version":"84de6181c634996552fdce82ddb8560c543776970963a0b6cf79291c1c52ed08","impliedFormat":99},{"version":"196d3246719b9fd0f124f171322aa8981afe09a4a5ae2f3b506134f01ef6ce89","impliedFormat":99},{"version":"ec7f1fb361239bd2f79647c4c12fe324918667a6eefef56e53d25560e9ccce77","impliedFormat":99},{"version":"c6f21fc4fd151b94b8ff0de2b16aa943d5635bfd30f9f5fee7b9e137e3474997","impliedFormat":99},{"version":"bee856262cdb790c78313066300a69002ea045ab9ed523315ea8225bbcaea7dd","impliedFormat":99},{"version":"3ffa16a7b3c57bcf12260e8570999d19fbfceb36dc23d381013678a2d8601ab6","impliedFormat":99},{"version":"444cfc5dc1d45b030c65aeda3dfb5973e8c55cba1d29886bb38f6d668b17f061","impliedFormat":99},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"69d327a9079d984240c360a3d7a52481761f98a7f26d901baf5d1835847577f3","signature":"ec624cdad0da030be5047cf1b9ef3522234916651214da29eb2697f0a1c9ea45"},{"version":"3fc28b80fbddf575ed60f2206863d99b7594157c1bdcf72d182d2d17d7e007df","signature":"a1889af19644b3eeaf6c8357cd3b33d3676a13c1e94ee2bf8acdd51c7f4feb04"},{"version":"dcd48e99bff07bb096e197535eefc1f68cb5fbca75e18fc11df47377a7eb61f6","impliedFormat":99},{"version":"df5b668c4174a120c129b8ab559ccf2a911677f5a8b9d5bc22898ffd4d16c2d3","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"d7c4fd426cb17d3d87b64c5a9dfded7c7084e1901ef87caadd232a1fea38d5a1","signature":"44258283f0fe85b63e2a1c83a209cb804ab4654085a3f0043b2262f03ccc2727"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"1978842c9a49f471f8ce1f05a90c16b67ee7ba61cae5c539b47e722ac6d44937","signature":"cb473d6bbffe7a12c6826d062487c44c0ddc213302207a8bfdd6622f28719beb"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"af2ac301e5b21fcc7817abf499de3cf66025fc3d53fadc56280d2bc413f0887b","signature":"71cec32132ea87938ec94c40187d676ad4c8ec842e29fb8505341dbb93778182"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"6201b44a285d6217d145689b24395c7d6f827308f2c93b3e345532066bad74d1","signature":"03d73b525ba1656b398ceb3088fe366372749826c5730b59874c7904a4c35675"},{"version":"e713b261d26868729b62ff43f1885446b57389614ad36a7a7ce165971d9d3dc5","signature":"b0c9fc2e51388a1f348242bd2c09cdc15bcd167e02c662039f4c72428b4e664f"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"84077c348324bd21c2371b24e06a65e2ea4be309dc23f907d92f475dcef553b7","signature":"b63c0b9101f87fa2b897a6f1faedf4c421e6839d2c53a34588002e0cd15f74f0"},{"version":"7e152eb04ba52095f29019db4cfaec8146da2bbe00e47d701a2c6b23501c0719","signature":"194091ea70368e13fd7546adc4097db6effd80971b3ec4b7a15fa27006e7e21a"},{"version":"71e362d93220598ee412247334180fda519e5765965c91429569aec22d783e32","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"9869fd1fb195257b166ee493302a066c98c4de0b7bfd869f72d40cb2f0d28eac","signature":"4cbefc2ee521f3b8b6538b41133dce668d261ec74d8456ebdf11a1a7964fcf96"},{"version":"a244da63a4fdf24fa69ffd2b90b3f57319abf5cfae6945d7d81324446a057a73","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"8eab869fddaed1cbbf96b69949cb6fe7cbe4395fa382b339d0278ee8ba48a39b","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"f57120367c14ca39f49fd2f11e60da48682534a0d00ef6456bba72d00525553d","signature":"578d6d6fe0efc9e23cebff5ef335eec7c3555a222cfda726b3f0393e87b82bef"},"eea2ca5aa2912da3489cd8b87e39d558c8860e27e4edeba4c378197d049664ba",{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"372997ea7117ed2afca54d8520e3f3abdbf0fcee5a9868053e3ef05a9193e9fb","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"6d6bc687b7955a989a371b7f210b48fd3b43489c71feaaf2d697af88d10cc3d3","signature":"8693af14cb7dd37597f91c2ecb2041b46b7adb8cddfce6bc7b284a886ef236dd"},{"version":"869831f378ee539fed92f60b0c0785d539975c6236a2c45c4441737376e50d16","signature":"5f0a3fcfc0b25a583e0da2fdf2ee3a70fc4a41b782f57fb39f82936af8ce4228"},{"version":"8aa5b6b14529fe5c06bcc9d9505bab6c15907da3c83a3c0fe570270ef40e653c","signature":"a25e39279b870f0a86f846662790fdf0fe0454f14d7503e61f7cb68b6d80a462"},{"version":"682d1de1e0cf7c40b8934248b47503dd5a0281622f2be738ec46c82903e276cb","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"927aa4ba40ea75c698540a04206b89eba44cdeb53515f557c186c6e070a7c485","signature":"6a1641235112fb6fb6fab11cc2c82e34264067f8fc24601685872b309bd8926f"},{"version":"ef66b2497320e870be78679c278d8098356a66ce0111aeeaea874e5476366999","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},"d28da413ca7707c3a1cbe902b531caa43154aaa5502d59eff922c71e1052052e",{"version":"e7bdcfc3d3439836bc7f68cd08102709f86c95e83705ee23886fbff3c0338634","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"b266334c67fa69ff67fded0c634f852bb1aa3f99ddbccd7f2e70757ce11c1cef","signature":"aec710ec6aef682d41ad375ae1ddf9618cb325995710bfc1e5184d16e26ed347"},"7c3e8cda9e24432cae40cf89d7eaba09497ad0bbdba27cf4827d91ad7843241b",{"version":"39cf82dd3e8e6466a46c883ffc6ea08e8cd450c905ed9459acf3539beaadedf3","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"53109586cad472a3d15485a3fd20c05baf2a2a0fa67d27d3732150cec2649386","signature":"75bc462ddf0da78b387f93e976eeef877f83f46fa3c42ca86d01689c42e791f0"},{"version":"db7809c1e442d856386b91e80d0cc8c462646d0ffc4e8983855691bfa7f27f82","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"a296d8c3d81d06a2730846b8b164db8efa70893cc2f43b3eb08fd6cc6821fe44","signature":"83a30c5ff777123be82d93d9a3385f4602fb8e903dbea0a1cc1e46f6dde88eb9"},{"version":"68e349161eb354d5b2c0abc0ff54068b2eef31d8cbc794d23e0ac18815379d9a","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"d3cfde44f8089768ebb08098c96d01ca260b88bccf238d55eee93f1c620ff5a5","impliedFormat":1},{"version":"293eadad9dead44c6fd1db6de552663c33f215c55a1bfa2802a1bceed88ff0ec","impliedFormat":1},{"version":"833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","impliedFormat":1},{"version":"08b2fae7b0f553ad9f79faec864b179fc58bc172e295a70943e8585dd85f600c","impliedFormat":1},{"version":"f12edf1672a94c578eca32216839604f1e1c16b40a1896198deabf99c882b340","impliedFormat":1},{"version":"e3498cf5e428e6c6b9e97bd88736f26d6cf147dedbfa5a8ad3ed8e05e059af8a","impliedFormat":1},{"version":"dba3f34531fd9b1b6e072928b6f885aa4d28dd6789cbd0e93563d43f4b62da53","impliedFormat":1},{"version":"f672c876c1a04a223cf2023b3d91e8a52bb1544c576b81bf64a8fec82be9969c","impliedFormat":1},{"version":"e4b03ddcf8563b1c0aee782a185286ed85a255ce8a30df8453aade2188bbc904","impliedFormat":1},{"version":"2329d90062487e1eaca87b5e06abcbbeeecf80a82f65f949fd332cfcf824b87b","impliedFormat":1},{"version":"25b3f581e12ede11e5739f57a86e8668fbc0124f6649506def306cad2c59d262","impliedFormat":1},{"version":"4fdb529707247a1a917a4626bfb6a293d52cd8ee57ccf03830ec91d39d606d6d","impliedFormat":1},{"version":"a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","impliedFormat":1},{"version":"5780b706cece027f0d4444fbb4e1af62dc51e19da7c3d3719f67b22b033859b9","impliedFormat":1},{"version":"4749a5d10b6e3b0bd6c8d90f9ba68a91a97aa0c2c9a340dd83306b2f349d6d34","impliedFormat":99},{"version":"dd1729e568bbd92727b6703f2340096d07476d29085b3ee2f49e78e6f2029d20","impliedFormat":99},{"version":"efdb6c1c0e195ea378a0b7cd0e808f65176bea14396dc8bdccda80551e66d73f","impliedFormat":99},{"version":"de328e8fd327cf362e090965057fbbf14f2085c78b70eb31b61ceeca8d6da01c","impliedFormat":99},{"version":"b9e0783285db8fca77f8c20df30b66b201f914bacbfe472b86dcacdba555f360","impliedFormat":99},{"version":"005f10cafe0939ae8d6a98e19c4ddf8b59faf3f9ae38dfa5907b82b9a6cb4de9","impliedFormat":1},{"version":"089c056ad8ecb34ee72cb831491ab72c214d8fb7ecf94b96a1b4736ab54397a1","impliedFormat":1},{"version":"e643ef3093cba63af26396ae8dc58dc542c241027749dcdf715f3d3209f79a03","impliedFormat":1},{"version":"f40e6338b8137033a5b4efbe01de45a4399f2c304648eace01d852cd05eb861e","impliedFormat":1},{"version":"89d879fae02696e226dbcb7444d6153158fa264bb646071988f19a2e422b314f","impliedFormat":1},{"version":"57de3f0b1730cf8439c8aa4686f78f38b170a9b55e7a8393ae6f8a524bb3ba5a","impliedFormat":1},{"version":"e933bd300ea4f6c724d222bf2d93a0ae2b1e748baa1db09cb71d67d563794b2d","impliedFormat":1},{"version":"c43d0df83d8bb68ab9e2795cf1ec896ff1b5fab2023c977f3777819bc6b5c880","impliedFormat":1},{"version":"bf810d50332562d1b223a7ce607e5f8dc42714d8a3fa7bf39afe33830e107bf7","impliedFormat":1},{"version":"f025aff69699033567ebb4925578dedb18f63b4aa185f85005451cfd5fc53343","impliedFormat":1},{"version":"3d36c36df6ce6c4c3651a5f804ab07fe1c9bb8ce7d40ef4134038c364b429cb3","impliedFormat":1},{"version":"e9243dd3c92d2c56a2edf96cbce8faf357caf9397b95acaa65e960ad36cb7235","impliedFormat":1},{"version":"a24a9c59b7baecbb85c0ace2c07c9c5b7c2330bb5a2ae5d766f6bbf68f75e727","impliedFormat":1},{"version":"3c264d6a0f6be4f8684cb9e025f32c9b131cca7199c658eea28f0dae1f439124","impliedFormat":1},{"version":"d3cd789b0eebd5cebde1404383fd32c610bec782c74a415aa05ab3593abc35c8","impliedFormat":1},{"version":"8c1babb42f52952a6593b678f4cfb4afea5dc91e5cfaf3ca922cdd2d23b1277a","impliedFormat":1},{"version":"04ebb965333800caba800cabd1e18b02e0e69ab6a6f8948f2d53211df00a193c","impliedFormat":1},{"version":"f8e2be107b3e756e0a1c4f5e195e69dce69d38d0ff5c0b0509933e970c6d915b","impliedFormat":1},{"version":"309e580094520f9675a85c406ab5d1de4735f74a38f36690d569dbc5341f36a8","impliedFormat":1},{"version":"c2fa79fd37e4b0e4040de9d8db1b79accb1f8f63b3458cd0e5dac9d4f9e6f3f1","impliedFormat":1},{"version":"4f0d1a7e2a5a8b85d69f60a7be2a6223827f5fec473ba2142279841a54e8a845","impliedFormat":1},{"version":"ae2fb62b3647083fe8299e95dbfab2063c8301e9a626f42be0f360a57e434797","impliedFormat":1},{"version":"f53d803d9c9c8acdbb82ef5c6b8f224d42be50e9ab8bc09c8a9a942717214f9a","impliedFormat":1},{"version":"d2d70166533a2233aa35977eecea4b08c2f0f2e6e7b56c12a1c613c5ebf2c384","impliedFormat":1},{"version":"1097820fae2d12eb60006de0b5d057105e60d165cf8a6e6125f9876e6335cde7","impliedFormat":1},{"version":"8f62905f50830a638fd1a5ff68d9c8f2c1347ff046908eeb9119d257e8e8ae4a","impliedFormat":1},{"version":"8b4d34279952175f972f1aa62e136248311889148eb40a3e4782b244cece09f3","impliedFormat":1},{"version":"d3c3cc0840704fe524dbe8a812290bfd303e43d3bd43dcaac83ee682d2e15be0","impliedFormat":1},{"version":"71725ba9235f9d2aa02839162b1df2df59fd9dd91c110a54ea02112243d7a4d9","impliedFormat":1},{"version":"80af0c272dcb64518f7768428cdf91d21966a7f24ed0dfc69fad964d4c2ed8c1","impliedFormat":1},{"version":"1dc9702aa16e3ada78c84aa96868a7e5502001c402918b6d85ed25acbe80fd51","impliedFormat":1},{"version":"35f891c1bc36c97469df06316c65a718956515c8b3bdbeb146b468c02493ef13","impliedFormat":1},{"version":"2e9b05d7db853315f44d824e13840e6fdf17d615d13170b5f5cf830442018dcd","impliedFormat":1},{"version":"11989ad8152cf54a9cf974b02c1f03f2416857df6c5946ba735eb20ff9b3e9c2","impliedFormat":99},{"version":"91d3d5a235f545fd37bebfea42fc512970a2142ef3d8d9a02246760696d0b688","signature":"76cd2308eec82ec68321658d6a8d9fbc8f63b56d6882094751015b9caad0ab39"},{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"c368f2790f6713acf830b247dbe062d6a944fb2c62e5a05f0bacc6a6e72b42d2","signature":"cef241a9446a68cfcbe3f505fac3e4957644e8a7a057c2d1790fc5ca42d09a34"},"1d414c6e11b2aadd645a9884f937841c9119c3558dade287285b54da3c8e72a5",{"version":"7917a2fe07645831ead6f594e6266e085a3793ed4a6b1fb78ffb1d3012c9d9d8","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"cf0c5219caf4b606222c14945c44d76bcdc1a6312121ed7bdcc32b3a3b2a8813","signature":"baef37c1e99cf830b70b7421dba981bb52cb8eae0497ed894fb17d6cf67d21ee"},{"version":"82a7e877473191ab90dc519aa09097a4b43d36e7deb027d4cdb2cb676e8e5da0","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"5b34de185d8fb150e61cdda35fc71c4fa485af11d7790ccde935554d20cbbf13","signature":"e8c963395cd68de31f68b0593acae1a3c5ad6078b03ac904f0bdf18f2afbd110"},{"version":"bff6eda0d22914281e87801ee098664f32063176fcbe664713d6e8c7cc48cd8c","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"7c190550df69783c671fa0f9a30c50543d919bd82380d1052c9c46a54d26ae20","signature":"8db75b77dd8c50ccc5d607ef8e01c54c90a5244d09657563fd8767844b95c656"},{"version":"a656c3ff19c527654a23734b4c1cbef7d4e93119ac29fcdd69ce8e6e71a01700","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"0eee6b522110f17e3f67d1f29e5e94e88167fafec5fc857df3f39fe177876564","signature":"17685c741b7bea45071dd46ea9dd31bb6a9968acea17381ff7e3c4bb4bdad1e8"},{"version":"4e33cf334c14d8efab531e253fce914ccc98af9f55082660a64f46d05f3979d3","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"171e8cb90f6401066b66a24e4a8f2b7c42286b6ffa574973ba74a8a2ff4c0c4a","signature":"20a1a76cd6676c38fb9c50f6e6d98bf4e20198915fbfe6e0ef976decd35d519f"},{"version":"d495f32bab8da6f0885e0d60af9fc773225e96a0f3e9bfacb10de45671d6acc7","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"46e85f45904254029ed52feb7bc0afdb627693aff2e54d609c83a757c65025ca","signature":"e7bec6a95fc9e95f870aed2997217de1c67c3733b1a1f3cb99de7e7cf82b5d08"},{"version":"9ada1fe6db948aba09cdda6756a21836b5eb85e1b3ff3094dec276dd28f74d2f","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"2e43332ad2beb725c7b30d3559ffc813cb81c8b095358dc767dcab1c239c9306","signature":"efe0a1bb8a0e84604cd9a90d7ae76078f303d9d637299bfae098b70103f58a64"},{"version":"7ea7b1d69797d6b504f3076a6ee4c77018b6c096c91e6f0f2d53eafaabdb1a2e","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"8466d36ef9e8f0398ecff46995ea0eb848e09c9b40be197b22a17c9025d51a86","signature":"78f4862bf4cb5ebabb029d2b71f72d4e7ba23d2ca59a9fd736af0a72e8ee17d7"},{"version":"d754fdc3356af0ed80b2057b978e601d28570ec2854d4e7345d0717de8f1849c","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},{"version":"075ecc1e827edcbb2812dae374e249fc0de73718c934b18dab29a82a1517b81c","signature":"47c2edcbdbcf34a8ba5819d67de40997e5b2b4e3aca2100fb9eb48b0754942f7"},"85f101dddbdcf688727070e8c8a362c742ef7f3e61cf9b838f742251139d21f0",{"version":"ddd578018a259d1c494c834bdd8707769d07d1eb64f87f5217560cd2181b9e93","signature":"da14a67372982ca6e605fea114900b492b3316618581634e0ce72afbcb09baca"},{"version":"6f270c21417b8023bb813ee30189b5ee4676c4ff7b2d59261d34413a276eb604","signature":"0f85a7c1fe33a91a589145067aca211a6c638c8f5423045e55aa4f1d39f223ed"},"5db7e0cbcd4feeb9a6ce1f7cd34a7736dc331c5aeb18320f7185001c0596c531",{"version":"bfc3f6350ca72099bdc4f04b357dd28a505c59405a139511d87edc6bdbf90b77","signature":"b52dcd199c97746007e4589749483d8b943e6bac0bbf6a90c0b9c7be86f9b793"},"70355f9ccf5e858d1dddbb30c56994434f8a3e492d9d80c306ab9e8ff0f1efa0",{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"a79e62f1e20467e11a904399b8b18b18c0c6eea6b50c1168bf215356d5bebfaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"d802f0e6b5188646d307f070d83512e8eb94651858de8a82d1e47f60fb6da4e2","affectsGlobalScope":true,"impliedFormat":1},{"version":"17bb4105d0ea2ab2bfcb4f77ff8585691d5569c90ae15f4fa8d5ff9fb42b910b","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"456fa0c0ab68731564917642b977c71c3b7682240685b118652fb9253c9a6429","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"2cbe0621042e2a68c7cbce5dfed3906a1862a16a7d496010636cdbdb91341c0f","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"a38efe83ff77c34e0f418a806a01ca3910c02ee7d64212a59d59bca6c2c38fa1","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"7b988bc259155186e6b09dd8b32856d9e45c8d261e63c19abaf590bb6550f922","affectsGlobalScope":true,"impliedFormat":1},{"version":"fe7b52f993f9336b595190f3c1fcc259bb2cf6dcb4ac8fdb1e0454cc5df7301e","impliedFormat":1},{"version":"e9b97d69510658d2f4199b7d384326b7c4053b9e6645f5c19e1c2a54ede427fc","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"81711af669f63d43ccb4c08e15beda796656dd46673d0def001c7055db53852d","affectsGlobalScope":true,"impliedFormat":1},{"version":"19d5f8d3930e9f99aa2c36258bf95abbe5adf7e889e6181872d1cdba7c9a7dd5","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"bdba81959361810be44bcfdd283f4d601e406ab5ad1d2bdff0ed480cf983c9d7","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"b326f4813b90d230ec3950f66bd5b5ce3971aac5fac67cfafc54aa07b39fd07f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c8420c7c2b778b334587a4c0311833b5212ff2f684ea37b2f0e2b117f1d7210d","impliedFormat":1},{"version":"b6b08215821c9833b0e8e30ea1ed178009f2f3ff5d7fae3865ee42f97cc87784","impliedFormat":1},{"version":"b795c3e47a26be91ac33d8115acdc37bfa41ecc701fb237c64a23da4d2b7e1d8","impliedFormat":1},{"version":"73cf6cc19f16c0191e4e9d497ab0c11c7b38f1ca3f01ad0f09a3a5a971aac4b8","impliedFormat":1},{"version":"528b62e4272e3ddfb50e8eed9e359dedea0a4d171c3eb8f337f4892aac37b24b","impliedFormat":1},{"version":"ed58b9974bb3114f39806c9c2c6258c4ffa6a255921976a7c53dfa94bf178f42","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"f72bc8fe16da67e4e3268599295797b202b95e54bd215a03f97e925dd1502a36","impliedFormat":1},{"version":"b1b6ee0d012aeebe11d776a155d8979730440082797695fc8e2a5c326285678f","impliedFormat":1},{"version":"45875bcae57270aeb3ebc73a5e3fb4c7b9d91d6b045f107c1d8513c28ece71c0","impliedFormat":1},{"version":"915e18c559321c0afaa8d34674d3eb77e1ded12c3e85bf2a9891ec48b07a1ca5","affectsGlobalScope":true,"impliedFormat":1},{"version":"e9727a118ce60808e62457c89762fe5a4e2be8e9fd0112d12432d1bafdba942f","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"70b57b5529051497e9f6482b76d91c0dcbb103d9ead8a0549f5bab8f65e5d031","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"3a90b9beac4c2bfdf6517faae0940a042b81652badf747df0a7c7593456f6ebe","impliedFormat":1},{"version":"8302157cd431b3943eed09ad439b4441826c673d9f870dcb0e1f48e891a4211e","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"125d792ec6c0c0f657d758055c494301cc5fdb327d9d9d5960b3f129aff76093","impliedFormat":1},{"version":"dba28a419aec76ed864ef43e5f577a5c99a010c32e5949fe4e17a4d57c58dd11","affectsGlobalScope":true,"impliedFormat":1},{"version":"2754d8221d77c7b382096651925eb476f1066b3348da4b73fe71ced7801edada","impliedFormat":1},{"version":"a5890565ed564c7b29eb1b1038d4e10c03a3f5231b0a8d48fea4b41ab19f4f46","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"98ffdf93dfdd206516971d28e3e473f417a5cfd41172e46b4ce45008f640588e","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"cee74f5970ffc01041e5bffc3f324c20450534af4054d2c043cb49dbbd4ec8f7","affectsGlobalScope":true,"impliedFormat":1},{"version":"1a654e0d950353614ba4637a8de4f9d367903a0692b748e11fccf8c880c99735","affectsGlobalScope":true,"impliedFormat":1},{"version":"42da246c46ca3fd421b6fd88bb4466cda7137cf33e87ba5ceeded30219c428bd","impliedFormat":1},{"version":"3a051941721a7f905544732b0eb819c8d88333a96576b13af08b82c4f17581e4","impliedFormat":1},{"version":"ac5ed35e649cdd8143131964336ab9076937fa91802ec760b3ea63b59175c10a","impliedFormat":1},{"version":"f2feb9696208311cdcf1936df2b7cbec96a3f0ab9d403952bf170546d4253a90","affectsGlobalScope":true,"impliedFormat":1},{"version":"db3d77167a7da6c5ba0c51c5b654820e3464093f21724ccd774c0b9bc3f81bc0","impliedFormat":1},{"version":"d9b6fd8640f6ad3f13ce9ce47d91061a698cf7763fed7f668e4f89709989aae5","impliedFormat":1}],"root":[60,[269,272],[274,314],[368,395]],"options":{"composite":false,"declaration":false,"declarationMap":false,"downlevelIteration":true,"experimentalDecorators":true,"importHelpers":true,"inlineSourceMap":true,"inlineSources":true,"module":7,"noEmitOnError":false,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noImplicitReturns":true,"noPropertyAccessFromIndexSignature":true,"outDir":"../../../..","removeComments":false,"strict":true,"target":9,"tsBuildInfoFile":"./.tsbuildinfo","useDefineForClassFields":false},"referencedMap":[[60,1],[393,2],[260,3],[265,4],[262,5],[264,6],[259,6],[261,7],[256,8],[63,9],[255,10],[253,11],[62,7],[61,7],[258,12],[254,7],[257,7],[273,13],[263,14],[266,15],[268,16],[267,17],[367,18],[333,19],[329,7],[332,20],[331,21],[330,22],[396,7],[448,23],[449,23],[450,24],[402,25],[451,26],[452,27],[453,28],[397,7],[400,29],[398,7],[399,7],[454,30],[455,31],[456,32],[457,33],[458,34],[459,35],[460,35],[461,36],[462,37],[463,38],[464,39],[403,7],[401,7],[465,40],[466,41],[467,42],[500,43],[468,44],[469,45],[470,46],[471,47],[472,48],[473,49],[474,50],[475,51],[476,52],[477,53],[478,53],[479,54],[480,7],[481,7],[482,55],[484,56],[483,57],[485,58],[486,59],[487,60],[488,61],[489,62],[490,63],[491,64],[492,65],[493,66],[494,67],[495,68],[496,69],[497,70],[404,7],[405,7],[406,7],[445,71],[446,7],[447,7],[498,72],[499,73],[407,7],[334,74],[336,75],[337,76],[335,77],[359,7],[360,78],[342,79],[354,80],[353,81],[351,82],[361,83],[339,7],[364,84],[346,7],[357,85],[356,86],[358,87],[362,7],[352,88],[345,89],[350,90],[363,91],[348,92],[343,7],[344,93],[365,94],[355,95],[349,91],[340,7],[366,96],[338,81],[341,7],[347,81],[252,97],[225,7],[203,98],[201,98],[251,99],[216,100],[215,100],[116,101],[67,102],[223,101],[224,101],[226,103],[227,101],[228,104],[127,105],[229,101],[200,101],[230,101],[231,106],[232,101],[233,100],[234,107],[235,101],[236,101],[237,101],[238,101],[239,100],[240,101],[241,101],[242,101],[243,101],[244,108],[245,101],[246,101],[247,101],[248,101],[249,101],[66,99],[69,104],[70,104],[71,104],[72,104],[73,104],[74,104],[75,104],[76,101],[78,109],[79,104],[77,104],[80,104],[81,104],[82,104],[83,104],[84,104],[85,104],[86,101],[87,104],[88,104],[89,104],[90,104],[91,104],[92,101],[93,104],[94,104],[95,104],[96,104],[97,104],[98,104],[99,101],[101,110],[100,104],[102,104],[103,104],[104,104],[105,104],[106,108],[107,101],[108,101],[122,111],[110,112],[111,104],[112,104],[113,101],[114,104],[115,104],[117,113],[118,104],[119,104],[120,104],[121,104],[123,104],[124,104],[125,104],[126,104],[128,114],[129,104],[130,104],[131,104],[132,101],[133,104],[134,115],[135,115],[136,115],[137,101],[138,104],[139,104],[140,104],[145,104],[141,104],[142,101],[143,104],[144,101],[146,104],[147,104],[148,104],[149,104],[150,104],[151,104],[152,101],[153,104],[154,104],[155,104],[156,104],[157,104],[158,104],[159,104],[160,104],[161,104],[162,104],[163,104],[164,104],[165,104],[166,104],[167,104],[168,104],[169,116],[170,104],[171,104],[172,104],[173,104],[174,104],[175,104],[176,101],[177,101],[178,101],[179,101],[180,101],[181,104],[182,104],[183,104],[184,104],[202,117],[250,101],[187,118],[186,119],[210,120],[209,121],[205,122],[204,121],[206,123],[195,124],[193,125],[208,126],[207,123],[194,7],[196,127],[109,128],[65,129],[64,104],[199,7],[191,130],[192,131],[189,7],[190,132],[188,104],[197,133],[68,134],[217,7],[218,7],[211,7],[214,100],[213,7],[219,7],[220,7],[212,135],[221,7],[222,7],[185,136],[198,137],[59,7],[57,7],[58,7],[10,7],[12,7],[11,7],[2,7],[13,7],[14,7],[15,7],[16,7],[17,7],[18,7],[19,7],[20,7],[3,7],[21,7],[22,7],[4,7],[23,7],[27,7],[24,7],[25,7],[26,7],[28,7],[29,7],[30,7],[5,7],[31,7],[32,7],[33,7],[34,7],[6,7],[38,7],[35,7],[36,7],[37,7],[39,7],[7,7],[40,7],[45,7],[46,7],[41,7],[42,7],[43,7],[44,7],[8,7],[50,7],[47,7],[48,7],[49,7],[51,7],[9,7],[52,7],[53,7],[54,7],[56,7],[55,7],[1,7],[423,138],[433,139],[422,138],[443,140],[414,141],[413,142],[442,143],[436,144],[441,145],[416,146],[430,147],[415,148],[439,149],[411,150],[410,143],[440,151],[412,152],[417,153],[418,7],[421,153],[408,7],[444,154],[434,155],[425,156],[426,157],[428,158],[424,159],[427,160],[437,143],[419,161],[420,162],[429,163],[409,164],[432,155],[431,153],[435,7],[438,165],[328,166],[320,167],[327,168],[322,7],[323,7],[321,169],[324,170],[315,7],[316,7],[317,166],[319,171],[325,7],[326,172],[318,173],[290,174],[293,175],[294,1],[390,176],[380,177],[381,178],[378,179],[379,180],[382,181],[383,182],[384,183],[385,184],[386,185],[387,186],[274,187],[287,188],[394,189],[395,190],[388,191],[389,192],[374,193],[375,194],[372,195],[373,196],[376,197],[377,198],[305,199],[308,200],[301,201],[302,202],[309,203],[310,204],[288,205],[289,206],[303,207],[304,208],[295,209],[300,210],[291,211],[292,212],[311,213],[312,214],[313,215],[371,216],[391,1],[392,217],[282,1],[283,218],[297,1],[298,219],[269,1],[272,220],[277,1],[278,221],[369,1],[370,222],[314,1],[368,223],[285,1],[286,224],[270,1],[271,225],[275,1],[276,226],[281,1],[284,227],[279,1],[280,228],[296,1],[299,229],[306,1],[307,230]],"semanticDiagnosticsPerFile":[60,269,270,274,275,277,279,281,282,285,288,290,291,293,294,295,296,297,301,303,305,306,309,311,313,314,369,372,374,376,378,380,382,384,386,388,390,391,393,394],"version":"5.8.3"} \ No newline at end of file diff --git a/.angular/cache/20.2.2/app/angular-compiler.db b/.angular/cache/20.2.2/app/angular-compiler.db new file mode 100644 index 0000000..1b16008 Binary files /dev/null and b/.angular/cache/20.2.2/app/angular-compiler.db differ diff --git a/.angular/cache/20.2.2/app/angular-compiler.db-lock b/.angular/cache/20.2.2/app/angular-compiler.db-lock new file mode 100644 index 0000000..fd26e21 Binary files /dev/null and b/.angular/cache/20.2.2/app/angular-compiler.db-lock differ diff --git a/.angular/cache/20.2.2/app/vite/com.chrome.devtools.json b/.angular/cache/20.2.2/app/vite/com.chrome.devtools.json new file mode 100644 index 0000000..b8ddeda --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/com.chrome.devtools.json @@ -0,0 +1,6 @@ +{ + "workspace": { + "root": "C:\\Users\\bruno\\Downloads\\newtube", + "uuid": "969ba79d-ef50-49c8-8372-7418cabbcb6f" + } +} \ No newline at end of file diff --git a/.angular/cache/20.2.2/app/vite/deps/@angular_common.js b/.angular/cache/20.2.2/app/vite/deps/@angular_common.js new file mode 100644 index 0000000..ce6ae2f --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/deps/@angular_common.js @@ -0,0 +1,205 @@ +import { + APP_BASE_HREF, + AsyncPipe, + BrowserPlatformLocation, + CommonModule, + CurrencyPipe, + DATE_PIPE_DEFAULT_OPTIONS, + DATE_PIPE_DEFAULT_TIMEZONE, + DatePipe, + DecimalPipe, + DomAdapter, + FormStyle, + FormatWidth, + HashLocationStrategy, + I18nPluralPipe, + I18nSelectPipe, + IMAGE_LOADER, + JsonPipe, + KeyValuePipe, + LOCATION_INITIALIZED, + Location, + LocationStrategy, + LowerCasePipe, + NgClass, + NgComponentOutlet, + NgForOf, + NgForOfContext, + NgIf, + NgIfContext, + NgLocaleLocalization, + NgLocalization, + NgOptimizedImage, + NgPlural, + NgPluralCase, + NgStyle, + NgSwitch, + NgSwitchCase, + NgSwitchDefault, + NgTemplateOutlet, + NullViewportScroller, + NumberFormatStyle, + NumberSymbol, + PLATFORM_BROWSER_ID, + PLATFORM_SERVER_ID, + PRECONNECT_CHECK_BLOCKLIST, + PathLocationStrategy, + PercentPipe, + PlatformLocation, + PlatformNavigation, + Plural, + SlicePipe, + TitleCasePipe, + TranslationWidth, + UpperCasePipe, + VERSION, + ViewportScroller, + WeekDay, + formatCurrency, + formatDate, + formatNumber, + formatPercent, + getCurrencySymbol, + getDOM, + getLocaleCurrencyCode, + getLocaleCurrencyName, + getLocaleCurrencySymbol, + getLocaleDateFormat, + getLocaleDateTimeFormat, + getLocaleDayNames, + getLocaleDayPeriods, + getLocaleDirection, + getLocaleEraNames, + getLocaleExtraDayPeriodRules, + getLocaleExtraDayPeriods, + getLocaleFirstDayOfWeek, + getLocaleId, + getLocaleMonthNames, + getLocaleNumberFormat, + getLocaleNumberSymbol, + getLocalePluralCase, + getLocaleTimeFormat, + getLocaleWeekEndRange, + getNumberOfCurrencyDigits, + isPlatformBrowser, + isPlatformServer, + normalizeQueryParams, + provideCloudflareLoader, + provideCloudinaryLoader, + provideImageKitLoader, + provideImgixLoader, + provideNetlifyLoader, + registerLocaleData, + setRootDomAdapter +} from "./chunk-H4LQPAO2.js"; +import { + XhrFactory, + parseCookieValue +} from "./chunk-OUSM42MY.js"; +import { + DOCUMENT, + IMAGE_CONFIG +} from "./chunk-FVA7C6JK.js"; +import "./chunk-HWYXSU2G.js"; +import "./chunk-JRFR6BLO.js"; +import "./chunk-MARUHEWW.js"; +import "./chunk-GOMI4DH3.js"; +export { + APP_BASE_HREF, + AsyncPipe, + BrowserPlatformLocation, + CommonModule, + CurrencyPipe, + DATE_PIPE_DEFAULT_OPTIONS, + DATE_PIPE_DEFAULT_TIMEZONE, + DOCUMENT, + DatePipe, + DecimalPipe, + FormStyle, + FormatWidth, + HashLocationStrategy, + I18nPluralPipe, + I18nSelectPipe, + IMAGE_CONFIG, + IMAGE_LOADER, + JsonPipe, + KeyValuePipe, + LOCATION_INITIALIZED, + Location, + LocationStrategy, + LowerCasePipe, + NgClass, + NgComponentOutlet, + NgForOf as NgFor, + NgForOf, + NgForOfContext, + NgIf, + NgIfContext, + NgLocaleLocalization, + NgLocalization, + NgOptimizedImage, + NgPlural, + NgPluralCase, + NgStyle, + NgSwitch, + NgSwitchCase, + NgSwitchDefault, + NgTemplateOutlet, + NumberFormatStyle, + NumberSymbol, + PRECONNECT_CHECK_BLOCKLIST, + PathLocationStrategy, + PercentPipe, + PlatformLocation, + Plural, + SlicePipe, + TitleCasePipe, + TranslationWidth, + UpperCasePipe, + VERSION, + ViewportScroller, + WeekDay, + XhrFactory, + formatCurrency, + formatDate, + formatNumber, + formatPercent, + getCurrencySymbol, + getLocaleCurrencyCode, + getLocaleCurrencyName, + getLocaleCurrencySymbol, + getLocaleDateFormat, + getLocaleDateTimeFormat, + getLocaleDayNames, + getLocaleDayPeriods, + getLocaleDirection, + getLocaleEraNames, + getLocaleExtraDayPeriodRules, + getLocaleExtraDayPeriods, + getLocaleFirstDayOfWeek, + getLocaleId, + getLocaleMonthNames, + getLocaleNumberFormat, + getLocaleNumberSymbol, + getLocalePluralCase, + getLocaleTimeFormat, + getLocaleWeekEndRange, + getNumberOfCurrencyDigits, + isPlatformBrowser, + isPlatformServer, + provideCloudflareLoader, + provideCloudinaryLoader, + provideImageKitLoader, + provideImgixLoader, + provideNetlifyLoader, + registerLocaleData, + DomAdapter as ɵDomAdapter, + NullViewportScroller as ɵNullViewportScroller, + PLATFORM_BROWSER_ID as ɵPLATFORM_BROWSER_ID, + PLATFORM_SERVER_ID as ɵPLATFORM_SERVER_ID, + PlatformNavigation as ɵPlatformNavigation, + getDOM as ɵgetDOM, + normalizeQueryParams as ɵnormalizeQueryParams, + parseCookieValue as ɵparseCookieValue, + setRootDomAdapter as ɵsetRootDomAdapter +}; diff --git a/.angular/cache/20.2.2/app/vite/deps/@angular_common.js.map b/.angular/cache/20.2.2/app/vite/deps/@angular_common.js.map new file mode 100644 index 0000000..9865211 --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/deps/@angular_common.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sourcesContent": [], + "mappings": "", + "names": [] +} diff --git a/.angular/cache/20.2.2/app/vite/deps/@angular_common_http.js b/.angular/cache/20.2.2/app/vite/deps/@angular_common_http.js new file mode 100644 index 0000000..b99c22f --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/deps/@angular_common_http.js @@ -0,0 +1,89 @@ +import { + FetchBackend, + HTTP_INTERCEPTORS, + HTTP_ROOT_INTERCEPTOR_FNS, + HTTP_TRANSFER_CACHE_ORIGIN_MAP, + HttpBackend, + HttpClient, + HttpClientJsonpModule, + HttpClientModule, + HttpClientXsrfModule, + HttpContext, + HttpContextToken, + HttpErrorResponse, + HttpEventType, + HttpFeatureKind, + HttpHandler, + HttpHeaderResponse, + HttpHeaders, + HttpInterceptorHandler, + HttpParams, + HttpRequest, + HttpResponse, + HttpResponseBase, + HttpStatusCode, + HttpUrlEncodingCodec, + HttpXhrBackend, + HttpXsrfTokenExtractor, + JsonpClientBackend, + JsonpInterceptor, + REQUESTS_CONTRIBUTE_TO_STABILITY, + httpResource, + provideHttpClient, + withFetch, + withHttpTransferCache, + withInterceptors, + withInterceptorsFromDi, + withJsonpSupport, + withNoXsrfProtection, + withRequestsMadeViaParent, + withXsrfConfiguration +} from "./chunk-5DRVFSXL.js"; +import "./chunk-OUSM42MY.js"; +import "./chunk-FVA7C6JK.js"; +import "./chunk-HWYXSU2G.js"; +import "./chunk-JRFR6BLO.js"; +import "./chunk-MARUHEWW.js"; +import "./chunk-GOMI4DH3.js"; +export { + FetchBackend, + HTTP_INTERCEPTORS, + HTTP_TRANSFER_CACHE_ORIGIN_MAP, + HttpBackend, + HttpClient, + HttpClientJsonpModule, + HttpClientModule, + HttpClientXsrfModule, + HttpContext, + HttpContextToken, + HttpErrorResponse, + HttpEventType, + HttpFeatureKind, + HttpHandler, + HttpHeaderResponse, + HttpHeaders, + HttpParams, + HttpRequest, + HttpResponse, + HttpResponseBase, + HttpStatusCode, + HttpUrlEncodingCodec, + HttpXhrBackend, + HttpXsrfTokenExtractor, + JsonpClientBackend, + JsonpInterceptor, + httpResource, + provideHttpClient, + withFetch, + withInterceptors, + withInterceptorsFromDi, + withJsonpSupport, + withNoXsrfProtection, + withRequestsMadeViaParent, + withXsrfConfiguration, + HTTP_ROOT_INTERCEPTOR_FNS as ɵHTTP_ROOT_INTERCEPTOR_FNS, + HttpInterceptorHandler as ɵHttpInterceptingHandler, + HttpInterceptorHandler as ɵHttpInterceptorHandler, + REQUESTS_CONTRIBUTE_TO_STABILITY as ɵREQUESTS_CONTRIBUTE_TO_STABILITY, + withHttpTransferCache as ɵwithHttpTransferCache +}; diff --git a/.angular/cache/20.2.2/app/vite/deps/@angular_common_http.js.map b/.angular/cache/20.2.2/app/vite/deps/@angular_common_http.js.map new file mode 100644 index 0000000..9865211 --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/deps/@angular_common_http.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sourcesContent": [], + "mappings": "", + "names": [] +} diff --git a/.angular/cache/20.2.2/app/vite/deps/@angular_core.js b/.angular/cache/20.2.2/app/vite/deps/@angular_core.js new file mode 100644 index 0000000..c0d4c19 --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/deps/@angular_core.js @@ -0,0 +1,1006 @@ +import { + ALLOW_MULTIPLE_PLATFORMS, + ANIMATIONS_DISABLED, + ANIMATION_MODULE_TYPE, + APP_BOOTSTRAP_LISTENER, + APP_ID, + APP_INITIALIZER, + AcxChangeDetectionStrategy, + AcxViewEncapsulation, + AfterRenderManager, + ApplicationInitStatus, + ApplicationModule, + ApplicationRef, + Attribute, + CLIENT_RENDER_MODE_FLAG, + COMPILER_OPTIONS, + CONTAINER_HEADER_OFFSET, + CSP_NONCE, + CUSTOM_ELEMENTS_SCHEMA, + ChangeDetectionScheduler, + ChangeDetectionSchedulerImpl, + ChangeDetectionStrategy, + ChangeDetectorRef, + Compiler, + CompilerFactory, + Component, + ComponentFactory, + ComponentFactory$1, + ComponentFactoryResolver$1, + ComponentRef, + ComponentRef$1, + Console, + ContentChild, + ContentChildren, + DEFAULT_CURRENCY_CODE, + DEFAULT_LOCALE_ID, + DEFER_BLOCK_CONFIG, + DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, + DEHYDRATED_BLOCK_REGISTRY, + DOCUMENT, + DebugElement, + DebugEventListener, + DebugNode, + DefaultIterableDiffer, + DeferBlockBehavior, + DeferBlockState, + DestroyRef, + Directive, + ENABLE_ROOT_COMPONENT_BOOTSTRAP, + ENVIRONMENT_INITIALIZER, + EffectScheduler, + ElementRef, + ElementRegistry, + EmbeddedViewRef, + EnvironmentInjector, + ErrorHandler, + EventEmitter, + FactoryTarget, + Framework, + HOST_TAG_NAME, + Host, + HostAttributeToken, + HostBinding, + HostListener, + HydrationStatus, + IMAGE_CONFIG, + IMAGE_CONFIG_DEFAULTS, + INJECTOR$1, + INJECTOR_SCOPE, + INTERNAL_APPLICATION_ERROR_HANDLER, + IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, + IS_HYDRATION_DOM_REUSE_ENABLED, + IS_INCREMENTAL_HYDRATION_ENABLED, + Inject, + Injectable, + InjectionToken, + Injector, + Input, + IterableDiffers, + JSACTION_BLOCK_ELEMENT_MAP, + JSACTION_EVENT_CONTRACT, + KeyValueDiffers, + LContext, + LOCALE_ID, + LocaleDataIndex, + MAX_ANIMATION_TIMEOUT, + MissingTranslationStrategy, + ModuleWithComponentFactories, + NG_COMP_DEF, + NG_DIR_DEF, + NG_ELEMENT_ID, + NG_INJ_DEF, + NG_MOD_DEF, + NG_PIPE_DEF, + NG_PROV_DEF, + NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, + NO_CHANGE, + NO_ERRORS_SCHEMA, + NgModule, + NgModuleFactory, + NgModuleFactory$1, + NgModuleRef, + NgModuleRef$1, + NgProbeToken, + NgZone, + NoopNgZone, + Optional, + Output, + OutputEmitterRef, + PACKAGE_ROOT_URL, + PERFORMANCE_MARK_PREFIX, + PLATFORM_ID, + PLATFORM_INITIALIZER, + PROVIDED_NG_ZONE, + PendingTasks, + PendingTasksInternal, + Pipe, + PlatformRef, + Query, + QueryList, + R3Injector, + REQUEST, + REQUEST_CONTEXT, + RESPONSE_INIT, + ReflectionCapabilities, + Renderer2, + RendererFactory2, + RendererStyleFlags2, + ResourceImpl, + RuntimeError, + SIGNAL, + SSR_CONTENT_INTEGRITY_MARKER, + Sanitizer, + SecurityContext, + Self, + SimpleChange, + SkipSelf, + TESTABILITY, + TESTABILITY_GETTER, + TRANSLATIONS, + TRANSLATIONS_FORMAT, + TemplateRef, + Testability, + TestabilityRegistry, + TimerScheduler, + TracingAction, + TracingService, + TransferState, + Type, + VERSION, + Version, + ViewChild, + ViewChildren, + ViewContainerRef, + ViewEncapsulation, + ViewRef, + ViewRef2, + XSS_SECURITY_URL, + ZONELESS_ENABLED, + _global, + _sanitizeHtml, + _sanitizeUrl, + afterEveryRender, + afterNextRender, + afterRenderEffect, + allowSanitizationBypassAndThrow, + annotateForHydration, + asNativeElements, + assertInInjectionContext, + assertNotInReactiveContext, + assertPlatform, + booleanAttribute, + bypassSanitizationTrustHtml, + bypassSanitizationTrustResourceUrl, + bypassSanitizationTrustScript, + bypassSanitizationTrustStyle, + bypassSanitizationTrustUrl, + clearResolutionOfComponentResourcesQueue, + compileComponent, + compileDirective, + compileNgModule, + compileNgModuleDefs, + compileNgModuleFactory, + compilePipe, + computed, + contentChild, + contentChildren, + convertToBitFlags, + createComponent, + createEnvironmentInjector, + createInjector, + createNgModule, + createNgModuleRef, + createOrReusePlatformInjector, + createPlatform, + createPlatformFactory, + defaultIterableDiffers, + defaultKeyValueDiffers, + defineInjectable, + depsTracker, + destroyPlatform, + devModeEqual, + disableProfiling, + effect, + enableProdMode, + enableProfiling, + enableProfiling2, + encapsulateResourceError, + findLocaleData, + flushModuleScopingQueueAsMuchAsPossible, + formatRuntimeError, + forwardRef, + generateStandaloneInDeclarationsError, + getAnimationElementRemovalRegistry, + getAsyncClassMetadataFn, + getClosestComponentName, + getComponentDef, + getDebugNode, + getDeferBlocks$1, + getDirectives, + getDocument, + getHostElement, + getInjectableDef, + getLContext, + getLocaleCurrencyCode, + getLocalePluralCase, + getModuleFactory, + getNgModuleById, + getOutputDestroyRef, + getPlatform, + getSanitizationBypassType, + getTransferState, + importProvidersFrom, + inferTagNameFromDefinition, + inject, + injectChangeDetectorRef, + input, + inputBinding, + internalCreateApplication, + internalProvideZoneChangeDetection, + isBoundToModule, + isComponentDefPendingResolution, + isDevMode, + isEnvironmentProviders, + isInjectable, + isNgModule, + isPromise, + isSignal, + isStandalone, + isSubscribable, + isViewDirty, + linkedSignal, + makeEnvironmentProviders, + makeStateKey, + markForRefresh, + mergeApplicationConfig, + model, + noSideEffects, + numberAttribute, + output, + outputBinding, + patchComponentDefWithScope, + performanceMarkFeature, + platformCore, + provideAppInitializer, + provideBrowserGlobalErrorListeners, + provideCheckNoChangesConfig, + provideEnvironmentInitializer, + provideNgReflectAttributes, + providePlatformInitializer, + provideZoneChangeDetection, + provideZonelessChangeDetection, + publishExternalGlobalUtil, + readHydrationInfo, + reflectComponentType, + registerLocaleData, + registerNgModuleType, + renderDeferBlockState, + resetCompiledComponents, + resetJitOptions, + resolveComponentResources, + resolveForwardRef, + resource, + restoreComponentResolutionQueue, + runInInjectionContext, + setAllowDuplicateNgModuleIdsForTest, + setAlternateWeakRefImpl, + setClassMetadata, + setClassMetadataAsync, + setCurrentInjector, + setDocument, + setInjectorProfilerContext, + setLocaleId, + setTestabilityGetter, + signal, + startMeasuring, + stopMeasuring, + store, + stringify, + transitiveScopesFor, + triggerResourceLoading, + truncateMiddle, + twoWayBinding, + unregisterAllLocaleData, + untracked, + unwrapSafeValue, + viewChild, + viewChildren, + withDomHydration, + withEventReplay, + withI18nSupport, + withIncrementalHydration, + ɵINPUT_SIGNAL_BRAND_WRITE_TYPE, + ɵassertType, + ɵgetUnknownElementStrictMode, + ɵgetUnknownPropertyStrictMode, + ɵsetClassDebugInfo, + ɵsetUnknownElementStrictMode, + ɵsetUnknownPropertyStrictMode, + ɵunwrapWritableSignal, + ɵɵAnimationsFeature, + ɵɵCopyDefinitionFeature, + ɵɵExternalStylesFeature, + ɵɵHostDirectivesFeature, + ɵɵInheritDefinitionFeature, + ɵɵNgOnChangesFeature, + ɵɵProvidersFeature, + ɵɵadvance, + ɵɵanimateEnter, + ɵɵanimateEnterListener, + ɵɵanimateLeave, + ɵɵanimateLeaveListener, + ɵɵariaProperty, + ɵɵattachSourceLocations, + ɵɵattribute, + ɵɵclassMap, + ɵɵclassProp, + ɵɵcomponentInstance, + ɵɵconditional, + ɵɵconditionalBranchCreate, + ɵɵconditionalCreate, + ɵɵcontentQuery, + ɵɵcontentQuerySignal, + ɵɵdeclareLet, + ɵɵdefer, + ɵɵdeferEnableTimerScheduling, + ɵɵdeferHydrateNever, + ɵɵdeferHydrateOnHover, + ɵɵdeferHydrateOnIdle, + ɵɵdeferHydrateOnImmediate, + ɵɵdeferHydrateOnInteraction, + ɵɵdeferHydrateOnTimer, + ɵɵdeferHydrateOnViewport, + ɵɵdeferHydrateWhen, + ɵɵdeferOnHover, + ɵɵdeferOnIdle, + ɵɵdeferOnImmediate, + ɵɵdeferOnInteraction, + ɵɵdeferOnTimer, + ɵɵdeferOnViewport, + ɵɵdeferPrefetchOnHover, + ɵɵdeferPrefetchOnIdle, + ɵɵdeferPrefetchOnImmediate, + ɵɵdeferPrefetchOnInteraction, + ɵɵdeferPrefetchOnTimer, + ɵɵdeferPrefetchOnViewport, + ɵɵdeferPrefetchWhen, + ɵɵdeferWhen, + ɵɵdefineComponent, + ɵɵdefineDirective, + ɵɵdefineInjectable, + ɵɵdefineInjector, + ɵɵdefineNgModule, + ɵɵdefinePipe, + ɵɵdirectiveInject, + ɵɵdisableBindings, + ɵɵdomElement, + ɵɵdomElementContainer, + ɵɵdomElementContainerEnd, + ɵɵdomElementContainerStart, + ɵɵdomElementEnd, + ɵɵdomElementStart, + ɵɵdomListener, + ɵɵdomProperty, + ɵɵdomTemplate, + ɵɵelement, + ɵɵelementContainer, + ɵɵelementContainerEnd, + ɵɵelementContainerStart, + ɵɵelementEnd, + ɵɵelementStart, + ɵɵenableBindings, + ɵɵgetComponentDepsFactory, + ɵɵgetCurrentView, + ɵɵgetInheritedFactory, + ɵɵgetReplaceMetadataURL, + ɵɵi18n, + ɵɵi18nApply, + ɵɵi18nAttributes, + ɵɵi18nEnd, + ɵɵi18nExp, + ɵɵi18nPostprocess, + ɵɵi18nStart, + ɵɵinject, + ɵɵinjectAttribute, + ɵɵinterpolate, + ɵɵinterpolate1, + ɵɵinterpolate2, + ɵɵinterpolate3, + ɵɵinterpolate4, + ɵɵinterpolate5, + ɵɵinterpolate6, + ɵɵinterpolate7, + ɵɵinterpolate8, + ɵɵinterpolateV, + ɵɵinvalidFactory, + ɵɵinvalidFactoryDep, + ɵɵlistener, + ɵɵloadQuery, + ɵɵnamespaceHTML, + ɵɵnamespaceMathML, + ɵɵnamespaceSVG, + ɵɵnextContext, + ɵɵngDeclareClassMetadata, + ɵɵngDeclareClassMetadataAsync, + ɵɵngDeclareComponent, + ɵɵngDeclareDirective, + ɵɵngDeclareFactory, + ɵɵngDeclareInjectable, + ɵɵngDeclareInjector, + ɵɵngDeclareNgModule, + ɵɵngDeclarePipe, + ɵɵpipe, + ɵɵpipeBind1, + ɵɵpipeBind2, + ɵɵpipeBind3, + ɵɵpipeBind4, + ɵɵpipeBindV, + ɵɵprojection, + ɵɵprojectionDef, + ɵɵproperty, + ɵɵpureFunction0, + ɵɵpureFunction1, + ɵɵpureFunction2, + ɵɵpureFunction3, + ɵɵpureFunction4, + ɵɵpureFunction5, + ɵɵpureFunction6, + ɵɵpureFunction7, + ɵɵpureFunction8, + ɵɵpureFunctionV, + ɵɵqueryAdvance, + ɵɵqueryRefresh, + ɵɵreadContextLet, + ɵɵreference, + ɵɵrepeater, + ɵɵrepeaterCreate, + ɵɵrepeaterTrackByIdentity, + ɵɵrepeaterTrackByIndex, + ɵɵreplaceMetadata, + ɵɵresetView, + ɵɵresolveBody, + ɵɵresolveDocument, + ɵɵresolveWindow, + ɵɵrestoreView, + ɵɵsanitizeHtml, + ɵɵsanitizeResourceUrl, + ɵɵsanitizeScript, + ɵɵsanitizeStyle, + ɵɵsanitizeUrl, + ɵɵsanitizeUrlOrResourceUrl, + ɵɵsetComponentScope, + ɵɵsetNgModuleScope, + ɵɵstoreLet, + ɵɵstyleMap, + ɵɵstyleProp, + ɵɵsyntheticHostListener, + ɵɵsyntheticHostProperty, + ɵɵtemplate, + ɵɵtemplateRefExtractor, + ɵɵtext, + ɵɵtextInterpolate, + ɵɵtextInterpolate1, + ɵɵtextInterpolate2, + ɵɵtextInterpolate3, + ɵɵtextInterpolate4, + ɵɵtextInterpolate5, + ɵɵtextInterpolate6, + ɵɵtextInterpolate7, + ɵɵtextInterpolate8, + ɵɵtextInterpolateV, + ɵɵtrustConstantHtml, + ɵɵtrustConstantResourceUrl, + ɵɵtwoWayBindingSet, + ɵɵtwoWayListener, + ɵɵtwoWayProperty, + ɵɵvalidateIframeAttribute, + ɵɵviewQuery, + ɵɵviewQuerySignal +} from "./chunk-FVA7C6JK.js"; +import "./chunk-HWYXSU2G.js"; +import "./chunk-JRFR6BLO.js"; +import "./chunk-MARUHEWW.js"; +import "./chunk-GOMI4DH3.js"; +export { + ANIMATION_MODULE_TYPE, + APP_BOOTSTRAP_LISTENER, + APP_ID, + APP_INITIALIZER, + ApplicationInitStatus, + ApplicationModule, + ApplicationRef, + Attribute, + COMPILER_OPTIONS, + CSP_NONCE, + CUSTOM_ELEMENTS_SCHEMA, + ChangeDetectionStrategy, + ChangeDetectorRef, + Compiler, + CompilerFactory, + Component, + ComponentFactory$1 as ComponentFactory, + ComponentFactoryResolver$1 as ComponentFactoryResolver, + ComponentRef$1 as ComponentRef, + ContentChild, + ContentChildren, + DEFAULT_CURRENCY_CODE, + DOCUMENT, + DebugElement, + DebugEventListener, + DebugNode, + DefaultIterableDiffer, + DestroyRef, + Directive, + ENVIRONMENT_INITIALIZER, + ElementRef, + EmbeddedViewRef, + EnvironmentInjector, + ErrorHandler, + EventEmitter, + HOST_TAG_NAME, + Host, + HostAttributeToken, + HostBinding, + HostListener, + INJECTOR$1 as INJECTOR, + Inject, + Injectable, + InjectionToken, + Injector, + Input, + IterableDiffers, + KeyValueDiffers, + LOCALE_ID, + MAX_ANIMATION_TIMEOUT, + MissingTranslationStrategy, + ModuleWithComponentFactories, + NO_ERRORS_SCHEMA, + NgModule, + NgModuleFactory$1 as NgModuleFactory, + NgModuleRef$1 as NgModuleRef, + NgProbeToken, + NgZone, + Optional, + Output, + OutputEmitterRef, + PACKAGE_ROOT_URL, + PLATFORM_ID, + PLATFORM_INITIALIZER, + PendingTasks, + Pipe, + PlatformRef, + Query, + QueryList, + REQUEST, + REQUEST_CONTEXT, + RESPONSE_INIT, + Renderer2, + RendererFactory2, + RendererStyleFlags2, + Sanitizer, + SecurityContext, + Self, + SimpleChange, + SkipSelf, + TRANSLATIONS, + TRANSLATIONS_FORMAT, + TemplateRef, + Testability, + TestabilityRegistry, + TransferState, + Type, + VERSION, + Version, + ViewChild, + ViewChildren, + ViewContainerRef, + ViewEncapsulation, + ViewRef2 as ViewRef, + afterEveryRender, + afterNextRender, + afterRenderEffect, + asNativeElements, + assertInInjectionContext, + assertNotInReactiveContext, + assertPlatform, + booleanAttribute, + computed, + contentChild, + contentChildren, + createComponent, + createEnvironmentInjector, + createNgModule, + createNgModuleRef, + createPlatform, + createPlatformFactory, + defineInjectable, + destroyPlatform, + effect, + enableProdMode, + enableProfiling, + forwardRef, + getDebugNode, + getModuleFactory, + getNgModuleById, + getPlatform, + importProvidersFrom, + inject, + input, + inputBinding, + isDevMode, + isSignal, + isStandalone, + linkedSignal, + makeEnvironmentProviders, + makeStateKey, + mergeApplicationConfig, + model, + numberAttribute, + output, + outputBinding, + platformCore, + provideAppInitializer, + provideBrowserGlobalErrorListeners, + provideCheckNoChangesConfig, + provideEnvironmentInitializer, + provideNgReflectAttributes, + providePlatformInitializer, + provideZoneChangeDetection, + provideZonelessChangeDetection, + reflectComponentType, + resolveForwardRef, + resource, + runInInjectionContext, + setTestabilityGetter, + signal, + twoWayBinding, + untracked, + viewChild, + viewChildren, + ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, + ANIMATIONS_DISABLED as ɵANIMATIONS_DISABLED, + AcxChangeDetectionStrategy as ɵAcxChangeDetectionStrategy, + AcxViewEncapsulation as ɵAcxViewEncapsulation, + AfterRenderManager as ɵAfterRenderManager, + CLIENT_RENDER_MODE_FLAG as ɵCLIENT_RENDER_MODE_FLAG, + CONTAINER_HEADER_OFFSET as ɵCONTAINER_HEADER_OFFSET, + ChangeDetectionScheduler as ɵChangeDetectionScheduler, + ChangeDetectionSchedulerImpl as ɵChangeDetectionSchedulerImpl, + ComponentFactory$1 as ɵComponentFactory, + Console as ɵConsole, + DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, + DEFER_BLOCK_CONFIG as ɵDEFER_BLOCK_CONFIG, + DEFER_BLOCK_DEPENDENCY_INTERCEPTOR as ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR, + DEHYDRATED_BLOCK_REGISTRY as ɵDEHYDRATED_BLOCK_REGISTRY, + DeferBlockBehavior as ɵDeferBlockBehavior, + DeferBlockState as ɵDeferBlockState, + ENABLE_ROOT_COMPONENT_BOOTSTRAP as ɵENABLE_ROOT_COMPONENT_BOOTSTRAP, + EffectScheduler as ɵEffectScheduler, + ElementRegistry as ɵElementRegistry, + Framework as ɵFramework, + HydrationStatus as ɵHydrationStatus, + IMAGE_CONFIG as ɵIMAGE_CONFIG, + IMAGE_CONFIG_DEFAULTS as ɵIMAGE_CONFIG_DEFAULTS, + INJECTOR_SCOPE as ɵINJECTOR_SCOPE, + ɵINPUT_SIGNAL_BRAND_WRITE_TYPE, + INTERNAL_APPLICATION_ERROR_HANDLER as ɵINTERNAL_APPLICATION_ERROR_HANDLER, + IS_ENABLED_BLOCKING_INITIAL_NAVIGATION as ɵIS_ENABLED_BLOCKING_INITIAL_NAVIGATION, + IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_ENABLED, + IS_INCREMENTAL_HYDRATION_ENABLED as ɵIS_INCREMENTAL_HYDRATION_ENABLED, + JSACTION_BLOCK_ELEMENT_MAP as ɵJSACTION_BLOCK_ELEMENT_MAP, + JSACTION_EVENT_CONTRACT as ɵJSACTION_EVENT_CONTRACT, + LContext as ɵLContext, + LocaleDataIndex as ɵLocaleDataIndex, + NG_COMP_DEF as ɵNG_COMP_DEF, + NG_DIR_DEF as ɵNG_DIR_DEF, + NG_ELEMENT_ID as ɵNG_ELEMENT_ID, + NG_INJ_DEF as ɵNG_INJ_DEF, + NG_MOD_DEF as ɵNG_MOD_DEF, + NG_PIPE_DEF as ɵNG_PIPE_DEF, + NG_PROV_DEF as ɵNG_PROV_DEF, + NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, + NO_CHANGE as ɵNO_CHANGE, + NgModuleFactory as ɵNgModuleFactory, + NoopNgZone as ɵNoopNgZone, + PERFORMANCE_MARK_PREFIX as ɵPERFORMANCE_MARK_PREFIX, + PROVIDED_NG_ZONE as ɵPROVIDED_NG_ZONE, + PendingTasksInternal as ɵPendingTasksInternal, + R3Injector as ɵR3Injector, + ReflectionCapabilities as ɵReflectionCapabilities, + ComponentFactory as ɵRender3ComponentFactory, + ComponentRef as ɵRender3ComponentRef, + NgModuleRef as ɵRender3NgModuleRef, + ResourceImpl as ɵResourceImpl, + RuntimeError as ɵRuntimeError, + SIGNAL as ɵSIGNAL, + SSR_CONTENT_INTEGRITY_MARKER as ɵSSR_CONTENT_INTEGRITY_MARKER, + TESTABILITY as ɵTESTABILITY, + TESTABILITY_GETTER as ɵTESTABILITY_GETTER, + TimerScheduler as ɵTimerScheduler, + TracingAction as ɵTracingAction, + TracingService as ɵTracingService, + ViewRef as ɵViewRef, + XSS_SECURITY_URL as ɵXSS_SECURITY_URL, + ZONELESS_ENABLED as ɵZONELESS_ENABLED, + _sanitizeHtml as ɵ_sanitizeHtml, + _sanitizeUrl as ɵ_sanitizeUrl, + allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, + annotateForHydration as ɵannotateForHydration, + ɵassertType, + bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, + bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, + bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, + bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, + bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, + clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, + compileComponent as ɵcompileComponent, + compileDirective as ɵcompileDirective, + compileNgModule as ɵcompileNgModule, + compileNgModuleDefs as ɵcompileNgModuleDefs, + compileNgModuleFactory as ɵcompileNgModuleFactory, + compilePipe as ɵcompilePipe, + convertToBitFlags as ɵconvertToBitFlags, + createInjector as ɵcreateInjector, + createOrReusePlatformInjector as ɵcreateOrReusePlatformInjector, + defaultIterableDiffers as ɵdefaultIterableDiffers, + defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, + depsTracker as ɵdepsTracker, + devModeEqual as ɵdevModeEqual, + disableProfiling as ɵdisableProfiling, + enableProfiling2 as ɵenableProfiling, + encapsulateResourceError as ɵencapsulateResourceError, + findLocaleData as ɵfindLocaleData, + flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, + formatRuntimeError as ɵformatRuntimeError, + generateStandaloneInDeclarationsError as ɵgenerateStandaloneInDeclarationsError, + getAnimationElementRemovalRegistry as ɵgetAnimationElementRemovalRegistry, + getAsyncClassMetadataFn as ɵgetAsyncClassMetadataFn, + getClosestComponentName as ɵgetClosestComponentName, + getComponentDef as ɵgetComponentDef, + getDebugNode as ɵgetDebugNode, + getDeferBlocks$1 as ɵgetDeferBlocks, + getDirectives as ɵgetDirectives, + getDocument as ɵgetDocument, + getHostElement as ɵgetHostElement, + getInjectableDef as ɵgetInjectableDef, + getLContext as ɵgetLContext, + getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, + getLocalePluralCase as ɵgetLocalePluralCase, + getOutputDestroyRef as ɵgetOutputDestroyRef, + getSanitizationBypassType as ɵgetSanitizationBypassType, + getTransferState as ɵgetTransferState, + ɵgetUnknownElementStrictMode, + ɵgetUnknownPropertyStrictMode, + _global as ɵglobal, + inferTagNameFromDefinition as ɵinferTagNameFromDefinition, + injectChangeDetectorRef as ɵinjectChangeDetectorRef, + internalCreateApplication as ɵinternalCreateApplication, + internalProvideZoneChangeDetection as ɵinternalProvideZoneChangeDetection, + isBoundToModule as ɵisBoundToModule, + isComponentDefPendingResolution as ɵisComponentDefPendingResolution, + isEnvironmentProviders as ɵisEnvironmentProviders, + isInjectable as ɵisInjectable, + isNgModule as ɵisNgModule, + isPromise as ɵisPromise, + isSubscribable as ɵisSubscribable, + isViewDirty as ɵisViewDirty, + markForRefresh as ɵmarkForRefresh, + noSideEffects as ɵnoSideEffects, + patchComponentDefWithScope as ɵpatchComponentDefWithScope, + performanceMarkFeature as ɵperformanceMarkFeature, + publishExternalGlobalUtil as ɵpublishExternalGlobalUtil, + readHydrationInfo as ɵreadHydrationInfo, + registerLocaleData as ɵregisterLocaleData, + renderDeferBlockState as ɵrenderDeferBlockState, + resetCompiledComponents as ɵresetCompiledComponents, + resetJitOptions as ɵresetJitOptions, + resolveComponentResources as ɵresolveComponentResources, + restoreComponentResolutionQueue as ɵrestoreComponentResolutionQueue, + setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, + setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, + ɵsetClassDebugInfo, + setClassMetadata as ɵsetClassMetadata, + setClassMetadataAsync as ɵsetClassMetadataAsync, + setCurrentInjector as ɵsetCurrentInjector, + setDocument as ɵsetDocument, + setInjectorProfilerContext as ɵsetInjectorProfilerContext, + setLocaleId as ɵsetLocaleId, + ɵsetUnknownElementStrictMode, + ɵsetUnknownPropertyStrictMode, + startMeasuring as ɵstartMeasuring, + stopMeasuring as ɵstopMeasuring, + store as ɵstore, + stringify as ɵstringify, + transitiveScopesFor as ɵtransitiveScopesFor, + triggerResourceLoading as ɵtriggerResourceLoading, + truncateMiddle as ɵtruncateMiddle, + unregisterAllLocaleData as ɵunregisterLocaleData, + unwrapSafeValue as ɵunwrapSafeValue, + ɵunwrapWritableSignal, + withDomHydration as ɵwithDomHydration, + withEventReplay as ɵwithEventReplay, + withI18nSupport as ɵwithI18nSupport, + withIncrementalHydration as ɵwithIncrementalHydration, + ɵɵAnimationsFeature, + ɵɵCopyDefinitionFeature, + ɵɵExternalStylesFeature, + FactoryTarget as ɵɵFactoryTarget, + ɵɵHostDirectivesFeature, + ɵɵInheritDefinitionFeature, + ɵɵNgOnChangesFeature, + ɵɵProvidersFeature, + ɵɵadvance, + ɵɵanimateEnter, + ɵɵanimateEnterListener, + ɵɵanimateLeave, + ɵɵanimateLeaveListener, + ɵɵariaProperty, + ɵɵattachSourceLocations, + ɵɵattribute, + ɵɵclassMap, + ɵɵclassProp, + ɵɵcomponentInstance, + ɵɵconditional, + ɵɵconditionalBranchCreate, + ɵɵconditionalCreate, + ɵɵcontentQuery, + ɵɵcontentQuerySignal, + ɵɵdeclareLet, + ɵɵdefer, + ɵɵdeferEnableTimerScheduling, + ɵɵdeferHydrateNever, + ɵɵdeferHydrateOnHover, + ɵɵdeferHydrateOnIdle, + ɵɵdeferHydrateOnImmediate, + ɵɵdeferHydrateOnInteraction, + ɵɵdeferHydrateOnTimer, + ɵɵdeferHydrateOnViewport, + ɵɵdeferHydrateWhen, + ɵɵdeferOnHover, + ɵɵdeferOnIdle, + ɵɵdeferOnImmediate, + ɵɵdeferOnInteraction, + ɵɵdeferOnTimer, + ɵɵdeferOnViewport, + ɵɵdeferPrefetchOnHover, + ɵɵdeferPrefetchOnIdle, + ɵɵdeferPrefetchOnImmediate, + ɵɵdeferPrefetchOnInteraction, + ɵɵdeferPrefetchOnTimer, + ɵɵdeferPrefetchOnViewport, + ɵɵdeferPrefetchWhen, + ɵɵdeferWhen, + ɵɵdefineComponent, + ɵɵdefineDirective, + ɵɵdefineInjectable, + ɵɵdefineInjector, + ɵɵdefineNgModule, + ɵɵdefinePipe, + ɵɵdirectiveInject, + ɵɵdisableBindings, + ɵɵdomElement, + ɵɵdomElementContainer, + ɵɵdomElementContainerEnd, + ɵɵdomElementContainerStart, + ɵɵdomElementEnd, + ɵɵdomElementStart, + ɵɵdomListener, + ɵɵdomProperty, + ɵɵdomTemplate, + ɵɵelement, + ɵɵelementContainer, + ɵɵelementContainerEnd, + ɵɵelementContainerStart, + ɵɵelementEnd, + ɵɵelementStart, + ɵɵenableBindings, + ɵɵgetComponentDepsFactory, + ɵɵgetCurrentView, + ɵɵgetInheritedFactory, + ɵɵgetReplaceMetadataURL, + ɵɵi18n, + ɵɵi18nApply, + ɵɵi18nAttributes, + ɵɵi18nEnd, + ɵɵi18nExp, + ɵɵi18nPostprocess, + ɵɵi18nStart, + ɵɵinject, + ɵɵinjectAttribute, + ɵɵinterpolate, + ɵɵinterpolate1, + ɵɵinterpolate2, + ɵɵinterpolate3, + ɵɵinterpolate4, + ɵɵinterpolate5, + ɵɵinterpolate6, + ɵɵinterpolate7, + ɵɵinterpolate8, + ɵɵinterpolateV, + ɵɵinvalidFactory, + ɵɵinvalidFactoryDep, + ɵɵlistener, + ɵɵloadQuery, + ɵɵnamespaceHTML, + ɵɵnamespaceMathML, + ɵɵnamespaceSVG, + ɵɵnextContext, + ɵɵngDeclareClassMetadata, + ɵɵngDeclareClassMetadataAsync, + ɵɵngDeclareComponent, + ɵɵngDeclareDirective, + ɵɵngDeclareFactory, + ɵɵngDeclareInjectable, + ɵɵngDeclareInjector, + ɵɵngDeclareNgModule, + ɵɵngDeclarePipe, + ɵɵpipe, + ɵɵpipeBind1, + ɵɵpipeBind2, + ɵɵpipeBind3, + ɵɵpipeBind4, + ɵɵpipeBindV, + ɵɵprojection, + ɵɵprojectionDef, + ɵɵproperty, + ɵɵpureFunction0, + ɵɵpureFunction1, + ɵɵpureFunction2, + ɵɵpureFunction3, + ɵɵpureFunction4, + ɵɵpureFunction5, + ɵɵpureFunction6, + ɵɵpureFunction7, + ɵɵpureFunction8, + ɵɵpureFunctionV, + ɵɵqueryAdvance, + ɵɵqueryRefresh, + ɵɵreadContextLet, + ɵɵreference, + registerNgModuleType as ɵɵregisterNgModuleType, + ɵɵrepeater, + ɵɵrepeaterCreate, + ɵɵrepeaterTrackByIdentity, + ɵɵrepeaterTrackByIndex, + ɵɵreplaceMetadata, + ɵɵresetView, + ɵɵresolveBody, + ɵɵresolveDocument, + ɵɵresolveWindow, + ɵɵrestoreView, + ɵɵsanitizeHtml, + ɵɵsanitizeResourceUrl, + ɵɵsanitizeScript, + ɵɵsanitizeStyle, + ɵɵsanitizeUrl, + ɵɵsanitizeUrlOrResourceUrl, + ɵɵsetComponentScope, + ɵɵsetNgModuleScope, + ɵɵstoreLet, + ɵɵstyleMap, + ɵɵstyleProp, + ɵɵsyntheticHostListener, + ɵɵsyntheticHostProperty, + ɵɵtemplate, + ɵɵtemplateRefExtractor, + ɵɵtext, + ɵɵtextInterpolate, + ɵɵtextInterpolate1, + ɵɵtextInterpolate2, + ɵɵtextInterpolate3, + ɵɵtextInterpolate4, + ɵɵtextInterpolate5, + ɵɵtextInterpolate6, + ɵɵtextInterpolate7, + ɵɵtextInterpolate8, + ɵɵtextInterpolateV, + ɵɵtrustConstantHtml, + ɵɵtrustConstantResourceUrl, + ɵɵtwoWayBindingSet, + ɵɵtwoWayListener, + ɵɵtwoWayProperty, + ɵɵvalidateIframeAttribute, + ɵɵviewQuery, + ɵɵviewQuerySignal +}; diff --git a/.angular/cache/20.2.2/app/vite/deps/@angular_core.js.map b/.angular/cache/20.2.2/app/vite/deps/@angular_core.js.map new file mode 100644 index 0000000..9865211 --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/deps/@angular_core.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sourcesContent": [], + "mappings": "", + "names": [] +} diff --git a/.angular/cache/20.2.2/app/vite/deps/@angular_forms.js b/.angular/cache/20.2.2/app/vite/deps/@angular_forms.js new file mode 100644 index 0000000..7b7f056 --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/deps/@angular_forms.js @@ -0,0 +1,6966 @@ +import { + getDOM +} from "./chunk-H4LQPAO2.js"; +import "./chunk-OUSM42MY.js"; +import { + ApplicationRef, + ChangeDetectorRef, + DestroyRef, + Directive, + ElementRef, + EventEmitter, + Host, + Inject, + Injectable, + InjectionToken, + Injector, + Input, + NgModule, + Optional, + Output, + Renderer2, + RuntimeError, + Self, + SkipSelf, + Version, + afterNextRender, + booleanAttribute, + computed, + forwardRef, + inject, + isPromise, + isSubscribable, + setClassMetadata, + signal, + untracked, + ɵɵInheritDefinitionFeature, + ɵɵNgOnChangesFeature, + ɵɵProvidersFeature, + ɵɵattribute, + ɵɵclassProp, + ɵɵdefineDirective, + ɵɵdefineInjectable, + ɵɵdefineInjector, + ɵɵdefineNgModule, + ɵɵdirectiveInject, + ɵɵgetInheritedFactory, + ɵɵlistener +} from "./chunk-FVA7C6JK.js"; +import { + forkJoin +} from "./chunk-HWYXSU2G.js"; +import "./chunk-JRFR6BLO.js"; +import { + Subject, + from, + map +} from "./chunk-MARUHEWW.js"; +import { + __spreadProps, + __spreadValues +} from "./chunk-GOMI4DH3.js"; + +// node_modules/@angular/forms/fesm2022/forms.mjs +var BaseControlValueAccessor = class _BaseControlValueAccessor { + _renderer; + _elementRef; + /** + * The registered callback function called when a change or input event occurs on the input + * element. + * @docs-private + */ + onChange = (_) => { + }; + /** + * The registered callback function called when a blur event occurs on the input element. + * @docs-private + */ + onTouched = () => { + }; + constructor(_renderer, _elementRef) { + this._renderer = _renderer; + this._elementRef = _elementRef; + } + /** + * Helper method that sets a property on a target element using the current Renderer + * implementation. + * @docs-private + */ + setProperty(key, value) { + this._renderer.setProperty(this._elementRef.nativeElement, key, value); + } + /** + * Registers a function called when the control is touched. + * @docs-private + */ + registerOnTouched(fn) { + this.onTouched = fn; + } + /** + * Registers a function called when the control value changes. + * @docs-private + */ + registerOnChange(fn) { + this.onChange = fn; + } + /** + * Sets the "disabled" property on the range input element. + * @docs-private + */ + setDisabledState(isDisabled) { + this.setProperty("disabled", isDisabled); + } + static ɵfac = function BaseControlValueAccessor_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _BaseControlValueAccessor)(ɵɵdirectiveInject(Renderer2), ɵɵdirectiveInject(ElementRef)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _BaseControlValueAccessor + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(BaseControlValueAccessor, [{ + type: Directive + }], () => [{ + type: Renderer2 + }, { + type: ElementRef + }], null); +})(); +var BuiltInControlValueAccessor = class _BuiltInControlValueAccessor extends BaseControlValueAccessor { + static ɵfac = /* @__PURE__ */ (() => { + let ɵBuiltInControlValueAccessor_BaseFactory; + return function BuiltInControlValueAccessor_Factory(__ngFactoryType__) { + return (ɵBuiltInControlValueAccessor_BaseFactory || (ɵBuiltInControlValueAccessor_BaseFactory = ɵɵgetInheritedFactory(_BuiltInControlValueAccessor)))(__ngFactoryType__ || _BuiltInControlValueAccessor); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _BuiltInControlValueAccessor, + features: [ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(BuiltInControlValueAccessor, [{ + type: Directive + }], null, null); +})(); +var NG_VALUE_ACCESSOR = new InjectionToken(ngDevMode ? "NgValueAccessor" : ""); +var CHECKBOX_VALUE_ACCESSOR = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => CheckboxControlValueAccessor), + multi: true +}; +var CheckboxControlValueAccessor = class _CheckboxControlValueAccessor extends BuiltInControlValueAccessor { + /** + * Sets the "checked" property on the input element. + * @docs-private + */ + writeValue(value) { + this.setProperty("checked", value); + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵCheckboxControlValueAccessor_BaseFactory; + return function CheckboxControlValueAccessor_Factory(__ngFactoryType__) { + return (ɵCheckboxControlValueAccessor_BaseFactory || (ɵCheckboxControlValueAccessor_BaseFactory = ɵɵgetInheritedFactory(_CheckboxControlValueAccessor)))(__ngFactoryType__ || _CheckboxControlValueAccessor); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _CheckboxControlValueAccessor, + selectors: [["input", "type", "checkbox", "formControlName", ""], ["input", "type", "checkbox", "formControl", ""], ["input", "type", "checkbox", "ngModel", ""]], + hostBindings: function CheckboxControlValueAccessor_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("change", function CheckboxControlValueAccessor_change_HostBindingHandler($event) { + return ctx.onChange($event.target.checked); + })("blur", function CheckboxControlValueAccessor_blur_HostBindingHandler() { + return ctx.onTouched(); + }); + } + }, + standalone: false, + features: [ɵɵProvidersFeature([CHECKBOX_VALUE_ACCESSOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(CheckboxControlValueAccessor, [{ + type: Directive, + args: [{ + selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]", + host: { + "(change)": "onChange($any($event.target).checked)", + "(blur)": "onTouched()" + }, + providers: [CHECKBOX_VALUE_ACCESSOR], + standalone: false + }] + }], null, null); +})(); +var DEFAULT_VALUE_ACCESSOR = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => DefaultValueAccessor), + multi: true +}; +function _isAndroid() { + const userAgent = getDOM() ? getDOM().getUserAgent() : ""; + return /android (\d+)/.test(userAgent.toLowerCase()); +} +var COMPOSITION_BUFFER_MODE = new InjectionToken(ngDevMode ? "CompositionEventMode" : ""); +var DefaultValueAccessor = class _DefaultValueAccessor extends BaseControlValueAccessor { + _compositionMode; + /** Whether the user is creating a composition string (IME events). */ + _composing = false; + constructor(renderer, elementRef, _compositionMode) { + super(renderer, elementRef); + this._compositionMode = _compositionMode; + if (this._compositionMode == null) { + this._compositionMode = !_isAndroid(); + } + } + /** + * Sets the "value" property on the input element. + * @docs-private + */ + writeValue(value) { + const normalizedValue = value == null ? "" : value; + this.setProperty("value", normalizedValue); + } + /** @internal */ + _handleInput(value) { + if (!this._compositionMode || this._compositionMode && !this._composing) { + this.onChange(value); + } + } + /** @internal */ + _compositionStart() { + this._composing = true; + } + /** @internal */ + _compositionEnd(value) { + this._composing = false; + this._compositionMode && this.onChange(value); + } + static ɵfac = function DefaultValueAccessor_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _DefaultValueAccessor)(ɵɵdirectiveInject(Renderer2), ɵɵdirectiveInject(ElementRef), ɵɵdirectiveInject(COMPOSITION_BUFFER_MODE, 8)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _DefaultValueAccessor, + selectors: [["input", "formControlName", "", 3, "type", "checkbox"], ["textarea", "formControlName", ""], ["input", "formControl", "", 3, "type", "checkbox"], ["textarea", "formControl", ""], ["input", "ngModel", "", 3, "type", "checkbox"], ["textarea", "ngModel", ""], ["", "ngDefaultControl", ""]], + hostBindings: function DefaultValueAccessor_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("input", function DefaultValueAccessor_input_HostBindingHandler($event) { + return ctx._handleInput($event.target.value); + })("blur", function DefaultValueAccessor_blur_HostBindingHandler() { + return ctx.onTouched(); + })("compositionstart", function DefaultValueAccessor_compositionstart_HostBindingHandler() { + return ctx._compositionStart(); + })("compositionend", function DefaultValueAccessor_compositionend_HostBindingHandler($event) { + return ctx._compositionEnd($event.target.value); + }); + } + }, + standalone: false, + features: [ɵɵProvidersFeature([DEFAULT_VALUE_ACCESSOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(DefaultValueAccessor, [{ + type: Directive, + args: [{ + selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]", + // TODO: vsavkin replace the above selector with the one below it once + // https://github.com/angular/angular/issues/3011 is implemented + // selector: '[ngModel],[formControl],[formControlName]', + host: { + "(input)": "_handleInput($any($event.target).value)", + "(blur)": "onTouched()", + "(compositionstart)": "_compositionStart()", + "(compositionend)": "_compositionEnd($any($event.target).value)" + }, + providers: [DEFAULT_VALUE_ACCESSOR], + standalone: false + }] + }], () => [{ + type: Renderer2 + }, { + type: ElementRef + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Inject, + args: [COMPOSITION_BUFFER_MODE] + }] + }], null); +})(); +function isEmptyInputValue(value) { + return value == null || lengthOrSize(value) === 0; +} +function lengthOrSize(value) { + if (value == null) { + return null; + } else if (Array.isArray(value) || typeof value === "string") { + return value.length; + } else if (value instanceof Set) { + return value.size; + } + return null; +} +var NG_VALIDATORS = new InjectionToken(ngDevMode ? "NgValidators" : ""); +var NG_ASYNC_VALIDATORS = new InjectionToken(ngDevMode ? "NgAsyncValidators" : ""); +var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; +var Validators = class { + /** + * @description + * Validator that requires the control's value to be greater than or equal to the provided number. + * + * @usageNotes + * + * ### Validate against a minimum of 3 + * + * ```ts + * const control = new FormControl(2, Validators.min(3)); + * + * console.log(control.errors); // {min: {min: 3, actual: 2}} + * ``` + * + * @returns A validator function that returns an error map with the + * `min` property if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static min(min) { + return minValidator(min); + } + /** + * @description + * Validator that requires the control's value to be less than or equal to the provided number. + * + * @usageNotes + * + * ### Validate against a maximum of 15 + * + * ```ts + * const control = new FormControl(16, Validators.max(15)); + * + * console.log(control.errors); // {max: {max: 15, actual: 16}} + * ``` + * + * @returns A validator function that returns an error map with the + * `max` property if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static max(max) { + return maxValidator(max); + } + /** + * @description + * Validator that requires the control have a non-empty value. + * + * @usageNotes + * + * ### Validate that the field is non-empty + * + * ```ts + * const control = new FormControl('', Validators.required); + * + * console.log(control.errors); // {required: true} + * ``` + * + * @returns An error map with the `required` property + * if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static required(control) { + return requiredValidator(control); + } + /** + * @description + * Validator that requires the control's value be true. This validator is commonly + * used for required checkboxes. + * + * @usageNotes + * + * ### Validate that the field value is true + * + * ```ts + * const control = new FormControl('some value', Validators.requiredTrue); + * + * console.log(control.errors); // {required: true} + * ``` + * + * @returns An error map that contains the `required` property + * set to `true` if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static requiredTrue(control) { + return requiredTrueValidator(control); + } + /** + * @description + * Validator that requires the control's value pass an email validation test. + * + * Tests the value using a [regular + * expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) + * pattern suitable for common use cases. The pattern is based on the definition of a valid email + * address in the [WHATWG HTML + * specification](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address) with + * some enhancements to incorporate more RFC rules (such as rules related to domain names and the + * lengths of different parts of the address). + * + * The differences from the WHATWG version include: + * - Disallow `local-part` (the part before the `@` symbol) to begin or end with a period (`.`). + * - Disallow `local-part` to be longer than 64 characters. + * - Disallow the whole address to be longer than 254 characters. + * + * If this pattern does not satisfy your business needs, you can use `Validators.pattern()` to + * validate the value against a different pattern. + * + * @usageNotes + * + * ### Validate that the field matches a valid email pattern + * + * ```ts + * const control = new FormControl('bad@', Validators.email); + * + * console.log(control.errors); // {email: true} + * ``` + * + * @returns An error map with the `email` property + * if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static email(control) { + return emailValidator(control); + } + /** + * @description + * Validator that requires the number of items in the control's value to be greater than or equal + * to the provided minimum length. This validator is also provided by default if you use + * the HTML5 `minlength` attribute. Note that the `minLength` validator is intended to be used + * only for types that have a numeric `length` or `size` property, such as strings, arrays or + * sets. The `minLength` validator logic is also not invoked for values when their `length` or + * `size` property is 0 (for example in case of an empty string or an empty array), to support + * optional controls. You can use the standard `required` validator if empty values should not be + * considered valid. + * + * @usageNotes + * + * ### Validate that the field has a minimum of 3 characters + * + * ```ts + * const control = new FormControl('ng', Validators.minLength(3)); + * + * console.log(control.errors); // {minlength: {requiredLength: 3, actualLength: 2}} + * ``` + * + * ```html + * + * ``` + * + * @returns A validator function that returns an error map with the + * `minlength` property if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static minLength(minLength) { + return minLengthValidator(minLength); + } + /** + * @description + * Validator that requires the number of items in the control's value to be less than or equal + * to the provided maximum length. This validator is also provided by default if you use + * the HTML5 `maxlength` attribute. Note that the `maxLength` validator is intended to be used + * only for types that have a numeric `length` or `size` property, such as strings, arrays or + * sets. + * + * @usageNotes + * + * ### Validate that the field has maximum of 5 characters + * + * ```ts + * const control = new FormControl('Angular', Validators.maxLength(5)); + * + * console.log(control.errors); // {maxlength: {requiredLength: 5, actualLength: 7}} + * ``` + * + * ```html + * + * ``` + * + * @returns A validator function that returns an error map with the + * `maxlength` property if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static maxLength(maxLength) { + return maxLengthValidator(maxLength); + } + /** + * @description + * Validator that requires the control's value to match a regex pattern. This validator is also + * provided by default if you use the HTML5 `pattern` attribute. + * + * @usageNotes + * + * ### Validate that the field only contains letters or spaces + * + * ```ts + * const control = new FormControl('1', Validators.pattern('[a-zA-Z ]*')); + * + * console.log(control.errors); // {pattern: {requiredPattern: '^[a-zA-Z ]*$', actualValue: '1'}} + * ``` + * + * ```html + * + * ``` + * + * ### Pattern matching with the global or sticky flag + * + * `RegExp` objects created with the `g` or `y` flags that are passed into `Validators.pattern` + * can produce different results on the same input when validations are run consecutively. This is + * due to how the behavior of `RegExp.prototype.test` is + * specified in [ECMA-262](https://tc39.es/ecma262/#sec-regexpbuiltinexec) + * (`RegExp` preserves the index of the last match when the global or sticky flag is used). + * Due to this behavior, it is recommended that when using + * `Validators.pattern` you **do not** pass in a `RegExp` object with either the global or sticky + * flag enabled. + * + * ```ts + * // Not recommended (since the `g` flag is used) + * const controlOne = new FormControl('1', Validators.pattern(/foo/g)); + * + * // Good + * const controlTwo = new FormControl('1', Validators.pattern(/foo/)); + * ``` + * + * @param pattern A regular expression to be used as is to test the values, or a string. + * If a string is passed, the `^` character is prepended and the `$` character is + * appended to the provided string (if not already present), and the resulting regular + * expression is used to test the values. + * + * @returns A validator function that returns an error map with the + * `pattern` property if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static pattern(pattern) { + return patternValidator(pattern); + } + /** + * @description + * Validator that performs no operation. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static nullValidator(control) { + return nullValidator(); + } + static compose(validators) { + return compose(validators); + } + /** + * @description + * Compose multiple async validators into a single function that returns the union + * of the individual error objects for the provided control. + * + * @returns A validator function that returns an error map with the + * merged error objects of the async validators if the validation check fails, otherwise `null`. + * + * @see {@link /api/forms/AbstractControl#updateValueAndValidity updateValueAndValidity} + * + */ + static composeAsync(validators) { + return composeAsync(validators); + } +}; +function minValidator(min) { + return (control) => { + if (control.value == null || min == null) { + return null; + } + const value = parseFloat(control.value); + return !isNaN(value) && value < min ? { + "min": { + "min": min, + "actual": control.value + } + } : null; + }; +} +function maxValidator(max) { + return (control) => { + if (control.value == null || max == null) { + return null; + } + const value = parseFloat(control.value); + return !isNaN(value) && value > max ? { + "max": { + "max": max, + "actual": control.value + } + } : null; + }; +} +function requiredValidator(control) { + return isEmptyInputValue(control.value) ? { + "required": true + } : null; +} +function requiredTrueValidator(control) { + return control.value === true ? null : { + "required": true + }; +} +function emailValidator(control) { + if (isEmptyInputValue(control.value)) { + return null; + } + return EMAIL_REGEXP.test(control.value) ? null : { + "email": true + }; +} +function minLengthValidator(minLength) { + return (control) => { + const length = control.value?.length ?? lengthOrSize(control.value); + if (length === null || length === 0) { + return null; + } + return length < minLength ? { + "minlength": { + "requiredLength": minLength, + "actualLength": length + } + } : null; + }; +} +function maxLengthValidator(maxLength) { + return (control) => { + const length = control.value?.length ?? lengthOrSize(control.value); + if (length !== null && length > maxLength) { + return { + "maxlength": { + "requiredLength": maxLength, + "actualLength": length + } + }; + } + return null; + }; +} +function patternValidator(pattern) { + if (!pattern) return nullValidator; + let regex; + let regexStr; + if (typeof pattern === "string") { + regexStr = ""; + if (pattern.charAt(0) !== "^") regexStr += "^"; + regexStr += pattern; + if (pattern.charAt(pattern.length - 1) !== "$") regexStr += "$"; + regex = new RegExp(regexStr); + } else { + regexStr = pattern.toString(); + regex = pattern; + } + return (control) => { + if (isEmptyInputValue(control.value)) { + return null; + } + const value = control.value; + return regex.test(value) ? null : { + "pattern": { + "requiredPattern": regexStr, + "actualValue": value + } + }; + }; +} +function nullValidator(control) { + return null; +} +function isPresent(o) { + return o != null; +} +function toObservable(value) { + const obs = isPromise(value) ? from(value) : value; + if ((typeof ngDevMode === "undefined" || ngDevMode) && !isSubscribable(obs)) { + let errorMessage = `Expected async validator to return Promise or Observable.`; + if (typeof value === "object") { + errorMessage += " Are you using a synchronous validator where an async validator is expected?"; + } + throw new RuntimeError(-1101, errorMessage); + } + return obs; +} +function mergeErrors(arrayOfErrors) { + let res = {}; + arrayOfErrors.forEach((errors) => { + res = errors != null ? __spreadValues(__spreadValues({}, res), errors) : res; + }); + return Object.keys(res).length === 0 ? null : res; +} +function executeValidators(control, validators) { + return validators.map((validator) => validator(control)); +} +function isValidatorFn(validator) { + return !validator.validate; +} +function normalizeValidators(validators) { + return validators.map((validator) => { + return isValidatorFn(validator) ? validator : (c) => validator.validate(c); + }); +} +function compose(validators) { + if (!validators) return null; + const presentValidators = validators.filter(isPresent); + if (presentValidators.length == 0) return null; + return function(control) { + return mergeErrors(executeValidators(control, presentValidators)); + }; +} +function composeValidators(validators) { + return validators != null ? compose(normalizeValidators(validators)) : null; +} +function composeAsync(validators) { + if (!validators) return null; + const presentValidators = validators.filter(isPresent); + if (presentValidators.length == 0) return null; + return function(control) { + const observables = executeValidators(control, presentValidators).map(toObservable); + return forkJoin(observables).pipe(map(mergeErrors)); + }; +} +function composeAsyncValidators(validators) { + return validators != null ? composeAsync(normalizeValidators(validators)) : null; +} +function mergeValidators(controlValidators, dirValidator) { + if (controlValidators === null) return [dirValidator]; + return Array.isArray(controlValidators) ? [...controlValidators, dirValidator] : [controlValidators, dirValidator]; +} +function getControlValidators(control) { + return control._rawValidators; +} +function getControlAsyncValidators(control) { + return control._rawAsyncValidators; +} +function makeValidatorsArray(validators) { + if (!validators) return []; + return Array.isArray(validators) ? validators : [validators]; +} +function hasValidator(validators, validator) { + return Array.isArray(validators) ? validators.includes(validator) : validators === validator; +} +function addValidators(validators, currentValidators) { + const current = makeValidatorsArray(currentValidators); + const validatorsToAdd = makeValidatorsArray(validators); + validatorsToAdd.forEach((v) => { + if (!hasValidator(current, v)) { + current.push(v); + } + }); + return current; +} +function removeValidators(validators, currentValidators) { + return makeValidatorsArray(currentValidators).filter((v) => !hasValidator(validators, v)); +} +var AbstractControlDirective = class { + /** + * @description + * Reports the value of the control if it is present, otherwise null. + */ + get value() { + return this.control ? this.control.value : null; + } + /** + * @description + * Reports whether the control is valid. A control is considered valid if no + * validation errors exist with the current value. + * If the control is not present, null is returned. + */ + get valid() { + return this.control ? this.control.valid : null; + } + /** + * @description + * Reports whether the control is invalid, meaning that an error exists in the input value. + * If the control is not present, null is returned. + */ + get invalid() { + return this.control ? this.control.invalid : null; + } + /** + * @description + * Reports whether a control is pending, meaning that async validation is occurring and + * errors are not yet available for the input value. If the control is not present, null is + * returned. + */ + get pending() { + return this.control ? this.control.pending : null; + } + /** + * @description + * Reports whether the control is disabled, meaning that the control is disabled + * in the UI and is exempt from validation checks and excluded from aggregate + * values of ancestor controls. If the control is not present, null is returned. + */ + get disabled() { + return this.control ? this.control.disabled : null; + } + /** + * @description + * Reports whether the control is enabled, meaning that the control is included in ancestor + * calculations of validity or value. If the control is not present, null is returned. + */ + get enabled() { + return this.control ? this.control.enabled : null; + } + /** + * @description + * Reports the control's validation errors. If the control is not present, null is returned. + */ + get errors() { + return this.control ? this.control.errors : null; + } + /** + * @description + * Reports whether the control is pristine, meaning that the user has not yet changed + * the value in the UI. If the control is not present, null is returned. + */ + get pristine() { + return this.control ? this.control.pristine : null; + } + /** + * @description + * Reports whether the control is dirty, meaning that the user has changed + * the value in the UI. If the control is not present, null is returned. + */ + get dirty() { + return this.control ? this.control.dirty : null; + } + /** + * @description + * Reports whether the control is touched, meaning that the user has triggered + * a `blur` event on it. If the control is not present, null is returned. + */ + get touched() { + return this.control ? this.control.touched : null; + } + /** + * @description + * Reports the validation status of the control. Possible values include: + * 'VALID', 'INVALID', 'DISABLED', and 'PENDING'. + * If the control is not present, null is returned. + */ + get status() { + return this.control ? this.control.status : null; + } + /** + * @description + * Reports whether the control is untouched, meaning that the user has not yet triggered + * a `blur` event on it. If the control is not present, null is returned. + */ + get untouched() { + return this.control ? this.control.untouched : null; + } + /** + * @description + * Returns a multicasting observable that emits a validation status whenever it is + * calculated for the control. If the control is not present, null is returned. + */ + get statusChanges() { + return this.control ? this.control.statusChanges : null; + } + /** + * @description + * Returns a multicasting observable of value changes for the control that emits every time the + * value of the control changes in the UI or programmatically. + * If the control is not present, null is returned. + */ + get valueChanges() { + return this.control ? this.control.valueChanges : null; + } + /** + * @description + * Returns an array that represents the path from the top-level form to this control. + * Each index is the string name of the control on that level. + */ + get path() { + return null; + } + /** + * Contains the result of merging synchronous validators into a single validator function + * (combined using `Validators.compose`). + */ + _composedValidatorFn; + /** + * Contains the result of merging asynchronous validators into a single validator function + * (combined using `Validators.composeAsync`). + */ + _composedAsyncValidatorFn; + /** + * Set of synchronous validators as they were provided while calling `setValidators` function. + * @internal + */ + _rawValidators = []; + /** + * Set of asynchronous validators as they were provided while calling `setAsyncValidators` + * function. + * @internal + */ + _rawAsyncValidators = []; + /** + * Sets synchronous validators for this directive. + * @internal + */ + _setValidators(validators) { + this._rawValidators = validators || []; + this._composedValidatorFn = composeValidators(this._rawValidators); + } + /** + * Sets asynchronous validators for this directive. + * @internal + */ + _setAsyncValidators(validators) { + this._rawAsyncValidators = validators || []; + this._composedAsyncValidatorFn = composeAsyncValidators(this._rawAsyncValidators); + } + /** + * @description + * Synchronous validator function composed of all the synchronous validators registered with this + * directive. + */ + get validator() { + return this._composedValidatorFn || null; + } + /** + * @description + * Asynchronous validator function composed of all the asynchronous validators registered with + * this directive. + */ + get asyncValidator() { + return this._composedAsyncValidatorFn || null; + } + /* + * The set of callbacks to be invoked when directive instance is being destroyed. + */ + _onDestroyCallbacks = []; + /** + * Internal function to register callbacks that should be invoked + * when directive instance is being destroyed. + * @internal + */ + _registerOnDestroy(fn) { + this._onDestroyCallbacks.push(fn); + } + /** + * Internal function to invoke all registered "on destroy" callbacks. + * Note: calling this function also clears the list of callbacks. + * @internal + */ + _invokeOnDestroyCallbacks() { + this._onDestroyCallbacks.forEach((fn) => fn()); + this._onDestroyCallbacks = []; + } + /** + * @description + * Resets the control with the provided value if the control is present. + */ + reset(value = void 0) { + if (this.control) this.control.reset(value); + } + /** + * @description + * Reports whether the control with the given path has the error specified. + * + * @param errorCode The code of the error to check + * @param path A list of control names that designates how to move from the current control + * to the control that should be queried for errors. + * + * @usageNotes + * For example, for the following `FormGroup`: + * + * ```ts + * form = new FormGroup({ + * address: new FormGroup({ street: new FormControl() }) + * }); + * ``` + * + * The path to the 'street' control from the root form would be 'address' -> 'street'. + * + * It can be provided to this method in one of two formats: + * + * 1. An array of string control names, e.g. `['address', 'street']` + * 1. A period-delimited list of control names in one string, e.g. `'address.street'` + * + * If no path is given, this method checks for the error on the current control. + * + * @returns whether the given error is present in the control at the given path. + * + * If the control is not present, false is returned. + */ + hasError(errorCode, path) { + return this.control ? this.control.hasError(errorCode, path) : false; + } + /** + * @description + * Reports error data for the control with the given path. + * + * @param errorCode The code of the error to check + * @param path A list of control names that designates how to move from the current control + * to the control that should be queried for errors. + * + * @usageNotes + * For example, for the following `FormGroup`: + * + * ```ts + * form = new FormGroup({ + * address: new FormGroup({ street: new FormControl() }) + * }); + * ``` + * + * The path to the 'street' control from the root form would be 'address' -> 'street'. + * + * It can be provided to this method in one of two formats: + * + * 1. An array of string control names, e.g. `['address', 'street']` + * 1. A period-delimited list of control names in one string, e.g. `'address.street'` + * + * @returns error data for that particular error. If the control or error is not present, + * null is returned. + */ + getError(errorCode, path) { + return this.control ? this.control.getError(errorCode, path) : null; + } +}; +var ControlContainer = class extends AbstractControlDirective { + /** + * @description + * The name for the control + */ + name; + /** + * @description + * The top-level form directive for the control. + */ + get formDirective() { + return null; + } + /** + * @description + * The path to this group. + */ + get path() { + return null; + } +}; +var NgControl = class extends AbstractControlDirective { + /** + * @description + * The parent form for the control. + * + * @internal + */ + _parent = null; + /** + * @description + * The name for the control + */ + name = null; + /** + * @description + * The value accessor for the control + */ + valueAccessor = null; +}; +var AbstractControlStatus = class { + _cd; + constructor(cd) { + this._cd = cd; + } + get isTouched() { + this._cd?.control?._touched?.(); + return !!this._cd?.control?.touched; + } + get isUntouched() { + return !!this._cd?.control?.untouched; + } + get isPristine() { + this._cd?.control?._pristine?.(); + return !!this._cd?.control?.pristine; + } + get isDirty() { + return !!this._cd?.control?.dirty; + } + get isValid() { + this._cd?.control?._status?.(); + return !!this._cd?.control?.valid; + } + get isInvalid() { + return !!this._cd?.control?.invalid; + } + get isPending() { + return !!this._cd?.control?.pending; + } + get isSubmitted() { + this._cd?._submitted?.(); + return !!this._cd?.submitted; + } +}; +var ngControlStatusHost = { + "[class.ng-untouched]": "isUntouched", + "[class.ng-touched]": "isTouched", + "[class.ng-pristine]": "isPristine", + "[class.ng-dirty]": "isDirty", + "[class.ng-valid]": "isValid", + "[class.ng-invalid]": "isInvalid", + "[class.ng-pending]": "isPending" +}; +var ngGroupStatusHost = __spreadProps(__spreadValues({}, ngControlStatusHost), { + "[class.ng-submitted]": "isSubmitted" +}); +var NgControlStatus = class _NgControlStatus extends AbstractControlStatus { + constructor(cd) { + super(cd); + } + static ɵfac = function NgControlStatus_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _NgControlStatus)(ɵɵdirectiveInject(NgControl, 2)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _NgControlStatus, + selectors: [["", "formControlName", ""], ["", "ngModel", ""], ["", "formControl", ""]], + hostVars: 14, + hostBindings: function NgControlStatus_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵclassProp("ng-untouched", ctx.isUntouched)("ng-touched", ctx.isTouched)("ng-pristine", ctx.isPristine)("ng-dirty", ctx.isDirty)("ng-valid", ctx.isValid)("ng-invalid", ctx.isInvalid)("ng-pending", ctx.isPending); + } + }, + standalone: false, + features: [ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgControlStatus, [{ + type: Directive, + args: [{ + selector: "[formControlName],[ngModel],[formControl]", + host: ngControlStatusHost, + standalone: false + }] + }], () => [{ + type: NgControl, + decorators: [{ + type: Self + }] + }], null); +})(); +var NgControlStatusGroup = class _NgControlStatusGroup extends AbstractControlStatus { + constructor(cd) { + super(cd); + } + static ɵfac = function NgControlStatusGroup_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _NgControlStatusGroup)(ɵɵdirectiveInject(ControlContainer, 10)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _NgControlStatusGroup, + selectors: [["", "formGroupName", ""], ["", "formArrayName", ""], ["", "ngModelGroup", ""], ["", "formGroup", ""], ["form", 3, "ngNoForm", ""], ["", "ngForm", ""]], + hostVars: 16, + hostBindings: function NgControlStatusGroup_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵclassProp("ng-untouched", ctx.isUntouched)("ng-touched", ctx.isTouched)("ng-pristine", ctx.isPristine)("ng-dirty", ctx.isDirty)("ng-valid", ctx.isValid)("ng-invalid", ctx.isInvalid)("ng-pending", ctx.isPending)("ng-submitted", ctx.isSubmitted); + } + }, + standalone: false, + features: [ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgControlStatusGroup, [{ + type: Directive, + args: [{ + selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]", + host: ngGroupStatusHost, + standalone: false + }] + }], () => [{ + type: ControlContainer, + decorators: [{ + type: Optional + }, { + type: Self + }] + }], null); +})(); +var formControlNameExample = ` +
+ +
+ + In your class: + + this.myGroup = new FormGroup({ + firstName: new FormControl() + });`; +var formGroupNameExample = ` +
+
+ +
+
+ + In your class: + + this.myGroup = new FormGroup({ + person: new FormGroup({ firstName: new FormControl() }) + });`; +var formArrayNameExample = ` +
+
+
+ +
+
+
+ + In your class: + + this.cityArray = new FormArray([new FormControl('SF')]); + this.myGroup = new FormGroup({ + cities: this.cityArray + });`; +var ngModelGroupExample = ` +
+
+ +
+
`; +var ngModelWithFormGroupExample = ` +
+ + +
+`; +function controlParentException(nameOrIndex) { + return new RuntimeError(1050, `formControlName must be used with a parent formGroup directive. You'll want to add a formGroup + directive and pass it an existing FormGroup instance (you can create one in your class). + + ${describeFormControl(nameOrIndex)} + + Example: + + ${formControlNameExample}`); +} +function describeFormControl(nameOrIndex) { + if (nameOrIndex == null || nameOrIndex === "") { + return ""; + } + const valueType = typeof nameOrIndex === "string" ? "name" : "index"; + return `Affected Form Control ${valueType}: "${nameOrIndex}"`; +} +function ngModelGroupException() { + return new RuntimeError(1051, `formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents + that also have a "form" prefix: formGroupName, formArrayName, or formGroup. + + Option 1: Update the parent to be formGroupName (reactive form strategy) + + ${formGroupNameExample} + + Option 2: Use ngModel instead of formControlName (template-driven strategy) + + ${ngModelGroupExample}`); +} +function missingFormException() { + return new RuntimeError(1052, `formGroup expects a FormGroup instance. Please pass one in. + + Example: + + ${formControlNameExample}`); +} +function groupParentException() { + return new RuntimeError(1053, `formGroupName must be used with a parent formGroup directive. You'll want to add a formGroup + directive and pass it an existing FormGroup instance (you can create one in your class). + + Example: + + ${formGroupNameExample}`); +} +function arrayParentException() { + return new RuntimeError(1054, `formArrayName must be used with a parent formGroup directive. You'll want to add a formGroup + directive and pass it an existing FormGroup instance (you can create one in your class). + + Example: + + ${formArrayNameExample}`); +} +var disabledAttrWarning = ` + It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true + when you set up this control in your component class, the disabled attribute will actually be set in the DOM for + you. We recommend using this approach to avoid 'changed after checked' errors. + + Example: + // Specify the \`disabled\` property at control creation time: + form = new FormGroup({ + first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), + last: new FormControl('Drew', Validators.required) + }); + + // Controls can also be enabled/disabled after creation: + form.get('first')?.enable(); + form.get('last')?.disable(); +`; +var asyncValidatorsDroppedWithOptsWarning = ` + It looks like you're constructing using a FormControl with both an options argument and an + async validators argument. Mixing these arguments will cause your async validators to be dropped. + You should either put all your validators in the options object, or in separate validators + arguments. For example: + + // Using validators arguments + fc = new FormControl(42, Validators.required, myAsyncValidator); + + // Using AbstractControlOptions + fc = new FormControl(42, {validators: Validators.required, asyncValidators: myAV}); + + // Do NOT mix them: async validators will be dropped! + fc = new FormControl(42, {validators: Validators.required}, /* Oops! */ myAsyncValidator); +`; +function ngModelWarning(directiveName) { + return ` + It looks like you're using ngModel on the same form field as ${directiveName}. + Support for using the ngModel input property and ngModelChange event with + reactive form directives has been deprecated in Angular v6 and will be removed + in a future version of Angular. + + For more information on this, see our API docs here: + https://angular.io/api/forms/${directiveName === "formControl" ? "FormControlDirective" : "FormControlName"}#use-with-ngmodel + `; +} +function describeKey(isFormGroup2, key) { + return isFormGroup2 ? `with name: '${key}'` : `at index: ${key}`; +} +function noControlsError(isFormGroup2) { + return ` + There are no form controls registered with this ${isFormGroup2 ? "group" : "array"} yet. If you're using ngModel, + you may want to check next tick (e.g. use setTimeout). + `; +} +function missingControlError(isFormGroup2, key) { + return `Cannot find form control ${describeKey(isFormGroup2, key)}`; +} +function missingControlValueError(isFormGroup2, key) { + return `Must supply a value for form control ${describeKey(isFormGroup2, key)}`; +} +var VALID = "VALID"; +var INVALID = "INVALID"; +var PENDING = "PENDING"; +var DISABLED = "DISABLED"; +var ControlEvent = class { +}; +var ValueChangeEvent = class extends ControlEvent { + value; + source; + constructor(value, source) { + super(); + this.value = value; + this.source = source; + } +}; +var PristineChangeEvent = class extends ControlEvent { + pristine; + source; + constructor(pristine, source) { + super(); + this.pristine = pristine; + this.source = source; + } +}; +var TouchedChangeEvent = class extends ControlEvent { + touched; + source; + constructor(touched, source) { + super(); + this.touched = touched; + this.source = source; + } +}; +var StatusChangeEvent = class extends ControlEvent { + status; + source; + constructor(status, source) { + super(); + this.status = status; + this.source = source; + } +}; +var FormSubmittedEvent = class extends ControlEvent { + source; + constructor(source) { + super(); + this.source = source; + } +}; +var FormResetEvent = class extends ControlEvent { + source; + constructor(source) { + super(); + this.source = source; + } +}; +function pickValidators(validatorOrOpts) { + return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.validators : validatorOrOpts) || null; +} +function coerceToValidator(validator) { + return Array.isArray(validator) ? composeValidators(validator) : validator || null; +} +function pickAsyncValidators(asyncValidator, validatorOrOpts) { + if (typeof ngDevMode === "undefined" || ngDevMode) { + if (isOptionsObj(validatorOrOpts) && asyncValidator) { + console.warn(asyncValidatorsDroppedWithOptsWarning); + } + } + return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.asyncValidators : asyncValidator) || null; +} +function coerceToAsyncValidator(asyncValidator) { + return Array.isArray(asyncValidator) ? composeAsyncValidators(asyncValidator) : asyncValidator || null; +} +function isOptionsObj(validatorOrOpts) { + return validatorOrOpts != null && !Array.isArray(validatorOrOpts) && typeof validatorOrOpts === "object"; +} +function assertControlPresent(parent, isGroup, key) { + const controls = parent.controls; + const collection = isGroup ? Object.keys(controls) : controls; + if (!collection.length) { + throw new RuntimeError(1e3, typeof ngDevMode === "undefined" || ngDevMode ? noControlsError(isGroup) : ""); + } + if (!controls[key]) { + throw new RuntimeError(1001, typeof ngDevMode === "undefined" || ngDevMode ? missingControlError(isGroup, key) : ""); + } +} +function assertAllValuesPresent(control, isGroup, value) { + control._forEachChild((_, key) => { + if (value[key] === void 0) { + throw new RuntimeError(1002, typeof ngDevMode === "undefined" || ngDevMode ? missingControlValueError(isGroup, key) : ""); + } + }); +} +var AbstractControl = class { + /** @internal */ + _pendingDirty = false; + /** + * Indicates that a control has its own pending asynchronous validation in progress. + * It also stores if the control should emit events when the validation status changes. + * + * @internal + */ + _hasOwnPendingAsyncValidator = null; + /** @internal */ + _pendingTouched = false; + /** @internal */ + _onCollectionChange = () => { + }; + /** @internal */ + _updateOn; + _parent = null; + _asyncValidationSubscription; + /** + * Contains the result of merging synchronous validators into a single validator function + * (combined using `Validators.compose`). + * + * @internal + */ + _composedValidatorFn; + /** + * Contains the result of merging asynchronous validators into a single validator function + * (combined using `Validators.composeAsync`). + * + * @internal + */ + _composedAsyncValidatorFn; + /** + * Synchronous validators as they were provided: + * - in `AbstractControl` constructor + * - as an argument while calling `setValidators` function + * - while calling the setter on the `validator` field (e.g. `control.validator = validatorFn`) + * + * @internal + */ + _rawValidators; + /** + * Asynchronous validators as they were provided: + * - in `AbstractControl` constructor + * - as an argument while calling `setAsyncValidators` function + * - while calling the setter on the `asyncValidator` field (e.g. `control.asyncValidator = + * asyncValidatorFn`) + * + * @internal + */ + _rawAsyncValidators; + /** + * The current value of the control. + * + * * For a `FormControl`, the current value. + * * For an enabled `FormGroup`, the values of enabled controls as an object + * with a key-value pair for each member of the group. + * * For a disabled `FormGroup`, the values of all controls as an object + * with a key-value pair for each member of the group. + * * For a `FormArray`, the values of enabled controls as an array. + * + */ + value; + /** + * Initialize the AbstractControl instance. + * + * @param validators The function or array of functions that is used to determine the validity of + * this control synchronously. + * @param asyncValidators The function or array of functions that is used to determine validity of + * this control asynchronously. + */ + constructor(validators, asyncValidators) { + this._assignValidators(validators); + this._assignAsyncValidators(asyncValidators); + } + /** + * Returns the function that is used to determine the validity of this control synchronously. + * If multiple validators have been added, this will be a single composed function. + * See `Validators.compose()` for additional information. + */ + get validator() { + return this._composedValidatorFn; + } + set validator(validatorFn) { + this._rawValidators = this._composedValidatorFn = validatorFn; + } + /** + * Returns the function that is used to determine the validity of this control asynchronously. + * If multiple validators have been added, this will be a single composed function. + * See `Validators.compose()` for additional information. + */ + get asyncValidator() { + return this._composedAsyncValidatorFn; + } + set asyncValidator(asyncValidatorFn) { + this._rawAsyncValidators = this._composedAsyncValidatorFn = asyncValidatorFn; + } + /** + * The parent control. + */ + get parent() { + return this._parent; + } + /** + * The validation status of the control. + * + * @see {@link FormControlStatus} + * + * These status values are mutually exclusive, so a control cannot be + * both valid AND invalid or invalid AND disabled. + */ + get status() { + return untracked(this.statusReactive); + } + set status(v) { + untracked(() => this.statusReactive.set(v)); + } + /** @internal */ + _status = computed(() => this.statusReactive(), ...ngDevMode ? [{ + debugName: "_status" + }] : []); + statusReactive = signal(void 0, ...ngDevMode ? [{ + debugName: "statusReactive" + }] : []); + /** + * A control is `valid` when its `status` is `VALID`. + * + * @see {@link AbstractControl.status} + * + * @returns True if the control has passed all of its validation tests, + * false otherwise. + */ + get valid() { + return this.status === VALID; + } + /** + * A control is `invalid` when its `status` is `INVALID`. + * + * @see {@link AbstractControl.status} + * + * @returns True if this control has failed one or more of its validation checks, + * false otherwise. + */ + get invalid() { + return this.status === INVALID; + } + /** + * A control is `pending` when its `status` is `PENDING`. + * + * @see {@link AbstractControl.status} + * + * @returns True if this control is in the process of conducting a validation check, + * false otherwise. + */ + get pending() { + return this.status == PENDING; + } + /** + * A control is `disabled` when its `status` is `DISABLED`. + * + * Disabled controls are exempt from validation checks and + * are not included in the aggregate value of their ancestor + * controls. + * + * @see {@link AbstractControl.status} + * + * @returns True if the control is disabled, false otherwise. + */ + get disabled() { + return this.status === DISABLED; + } + /** + * A control is `enabled` as long as its `status` is not `DISABLED`. + * + * @returns True if the control has any status other than 'DISABLED', + * false if the status is 'DISABLED'. + * + * @see {@link AbstractControl.status} + * + */ + get enabled() { + return this.status !== DISABLED; + } + /** + * An object containing any errors generated by failing validation, + * or null if there are no errors. + */ + errors; + /** + * A control is `pristine` if the user has not yet changed + * the value in the UI. + * + * @returns True if the user has not yet changed the value in the UI; compare `dirty`. + * Programmatic changes to a control's value do not mark it dirty. + */ + get pristine() { + return untracked(this.pristineReactive); + } + set pristine(v) { + untracked(() => this.pristineReactive.set(v)); + } + /** @internal */ + _pristine = computed(() => this.pristineReactive(), ...ngDevMode ? [{ + debugName: "_pristine" + }] : []); + pristineReactive = signal(true, ...ngDevMode ? [{ + debugName: "pristineReactive" + }] : []); + /** + * A control is `dirty` if the user has changed the value + * in the UI. + * + * @returns True if the user has changed the value of this control in the UI; compare `pristine`. + * Programmatic changes to a control's value do not mark it dirty. + */ + get dirty() { + return !this.pristine; + } + /** + * True if the control is marked as `touched`. + * + * A control is marked `touched` once the user has triggered + * a `blur` event on it. + */ + get touched() { + return untracked(this.touchedReactive); + } + set touched(v) { + untracked(() => this.touchedReactive.set(v)); + } + /** @internal */ + _touched = computed(() => this.touchedReactive(), ...ngDevMode ? [{ + debugName: "_touched" + }] : []); + touchedReactive = signal(false, ...ngDevMode ? [{ + debugName: "touchedReactive" + }] : []); + /** + * True if the control has not been marked as touched + * + * A control is `untouched` if the user has not yet triggered + * a `blur` event on it. + */ + get untouched() { + return !this.touched; + } + /** + * Exposed as observable, see below. + * + * @internal + */ + _events = new Subject(); + /** + * A multicasting observable that emits an event every time the state of the control changes. + * It emits for value, status, pristine or touched changes. + * + * **Note**: On value change, the emit happens right after a value of this control is updated. The + * value of a parent control (for example if this FormControl is a part of a FormGroup) is updated + * later, so accessing a value of a parent control (using the `value` property) from the callback + * of this event might result in getting a value that has not been updated yet. Subscribe to the + * `events` of the parent control instead. + * For other event types, the events are emitted after the parent control has been updated. + * + */ + events = this._events.asObservable(); + /** + * A multicasting observable that emits an event every time the value of the control changes, in + * the UI or programmatically. It also emits an event each time you call enable() or disable() + * without passing along {emitEvent: false} as a function argument. + * + * **Note**: the emit happens right after a value of this control is updated. The value of a + * parent control (for example if this FormControl is a part of a FormGroup) is updated later, so + * accessing a value of a parent control (using the `value` property) from the callback of this + * event might result in getting a value that has not been updated yet. Subscribe to the + * `valueChanges` event of the parent control instead. + */ + valueChanges; + /** + * A multicasting observable that emits an event every time the validation `status` of the control + * recalculates. + * + * @see {@link FormControlStatus} + * @see {@link AbstractControl.status} + */ + statusChanges; + /** + * Reports the update strategy of the `AbstractControl` (meaning + * the event on which the control updates itself). + * Possible values: `'change'` | `'blur'` | `'submit'` + * Default value: `'change'` + */ + get updateOn() { + return this._updateOn ? this._updateOn : this.parent ? this.parent.updateOn : "change"; + } + /** + * Sets the synchronous validators that are active on this control. Calling + * this overwrites any existing synchronous validators. + * + * When you add or remove a validator at run time, you must call + * `updateValueAndValidity()` for the new validation to take effect. + * + * If you want to add a new validator without affecting existing ones, consider + * using `addValidators()` method instead. + */ + setValidators(validators) { + this._assignValidators(validators); + } + /** + * Sets the asynchronous validators that are active on this control. Calling this + * overwrites any existing asynchronous validators. + * + * When you add or remove a validator at run time, you must call + * `updateValueAndValidity()` for the new validation to take effect. + * + * If you want to add a new validator without affecting existing ones, consider + * using `addAsyncValidators()` method instead. + */ + setAsyncValidators(validators) { + this._assignAsyncValidators(validators); + } + /** + * Add a synchronous validator or validators to this control, without affecting other validators. + * + * When you add or remove a validator at run time, you must call + * `updateValueAndValidity()` for the new validation to take effect. + * + * Adding a validator that already exists will have no effect. If duplicate validator functions + * are present in the `validators` array, only the first instance would be added to a form + * control. + * + * @param validators The new validator function or functions to add to this control. + */ + addValidators(validators) { + this.setValidators(addValidators(validators, this._rawValidators)); + } + /** + * Add an asynchronous validator or validators to this control, without affecting other + * validators. + * + * When you add or remove a validator at run time, you must call + * `updateValueAndValidity()` for the new validation to take effect. + * + * Adding a validator that already exists will have no effect. + * + * @param validators The new asynchronous validator function or functions to add to this control. + */ + addAsyncValidators(validators) { + this.setAsyncValidators(addValidators(validators, this._rawAsyncValidators)); + } + /** + * Remove a synchronous validator from this control, without affecting other validators. + * Validators are compared by function reference; you must pass a reference to the exact same + * validator function as the one that was originally set. If a provided validator is not found, + * it is ignored. + * + * @usageNotes + * + * ### Reference to a ValidatorFn + * + * ``` + * // Reference to the RequiredValidator + * const ctrl = new FormControl('', Validators.required); + * ctrl.removeValidators(Validators.required); + * + * // Reference to anonymous function inside MinValidator + * const minValidator = Validators.min(3); + * const ctrl = new FormControl('', minValidator); + * expect(ctrl.hasValidator(minValidator)).toEqual(true) + * expect(ctrl.hasValidator(Validators.min(3))).toEqual(false) + * + * ctrl.removeValidators(minValidator); + * ``` + * + * When you add or remove a validator at run time, you must call + * `updateValueAndValidity()` for the new validation to take effect. + * + * @param validators The validator or validators to remove. + */ + removeValidators(validators) { + this.setValidators(removeValidators(validators, this._rawValidators)); + } + /** + * Remove an asynchronous validator from this control, without affecting other validators. + * Validators are compared by function reference; you must pass a reference to the exact same + * validator function as the one that was originally set. If a provided validator is not found, it + * is ignored. + * + * When you add or remove a validator at run time, you must call + * `updateValueAndValidity()` for the new validation to take effect. + * + * @param validators The asynchronous validator or validators to remove. + */ + removeAsyncValidators(validators) { + this.setAsyncValidators(removeValidators(validators, this._rawAsyncValidators)); + } + /** + * Check whether a synchronous validator function is present on this control. The provided + * validator must be a reference to the exact same function that was provided. + * + * @usageNotes + * + * ### Reference to a ValidatorFn + * + * ``` + * // Reference to the RequiredValidator + * const ctrl = new FormControl(0, Validators.required); + * expect(ctrl.hasValidator(Validators.required)).toEqual(true) + * + * // Reference to anonymous function inside MinValidator + * const minValidator = Validators.min(3); + * const ctrl = new FormControl(0, minValidator); + * expect(ctrl.hasValidator(minValidator)).toEqual(true) + * expect(ctrl.hasValidator(Validators.min(3))).toEqual(false) + * ``` + * + * @param validator The validator to check for presence. Compared by function reference. + * @returns Whether the provided validator was found on this control. + */ + hasValidator(validator) { + return hasValidator(this._rawValidators, validator); + } + /** + * Check whether an asynchronous validator function is present on this control. The provided + * validator must be a reference to the exact same function that was provided. + * + * @param validator The asynchronous validator to check for presence. Compared by function + * reference. + * @returns Whether the provided asynchronous validator was found on this control. + */ + hasAsyncValidator(validator) { + return hasValidator(this._rawAsyncValidators, validator); + } + /** + * Empties out the synchronous validator list. + * + * When you add or remove a validator at run time, you must call + * `updateValueAndValidity()` for the new validation to take effect. + * + */ + clearValidators() { + this.validator = null; + } + /** + * Empties out the async validator list. + * + * When you add or remove a validator at run time, you must call + * `updateValueAndValidity()` for the new validation to take effect. + * + */ + clearAsyncValidators() { + this.asyncValidator = null; + } + markAsTouched(opts = {}) { + const changed = this.touched === false; + this.touched = true; + const sourceControl = opts.sourceControl ?? this; + if (this._parent && !opts.onlySelf) { + this._parent.markAsTouched(__spreadProps(__spreadValues({}, opts), { + sourceControl + })); + } + if (changed && opts.emitEvent !== false) { + this._events.next(new TouchedChangeEvent(true, sourceControl)); + } + } + /** + * Marks the control and all its descendant controls as `dirty`. + * @see {@link markAsDirty()} + * + * @param opts Configuration options that determine how the control propagates changes + * and emits events after marking is applied. + * * `emitEvent`: When true or not supplied (the default), the `events` + * observable emits a `PristineChangeEvent` with the `pristine` property being `false`. + * When false, no events are emitted. + */ + markAllAsDirty(opts = {}) { + this.markAsDirty({ + onlySelf: true, + emitEvent: opts.emitEvent, + sourceControl: this + }); + this._forEachChild((control) => control.markAllAsDirty(opts)); + } + /** + * Marks the control and all its descendant controls as `touched`. + * @see {@link markAsTouched()} + * + * @param opts Configuration options that determine how the control propagates changes + * and emits events after marking is applied. + * * `emitEvent`: When true or not supplied (the default), the `events` + * observable emits a `TouchedChangeEvent` with the `touched` property being `true`. + * When false, no events are emitted. + */ + markAllAsTouched(opts = {}) { + this.markAsTouched({ + onlySelf: true, + emitEvent: opts.emitEvent, + sourceControl: this + }); + this._forEachChild((control) => control.markAllAsTouched(opts)); + } + markAsUntouched(opts = {}) { + const changed = this.touched === true; + this.touched = false; + this._pendingTouched = false; + const sourceControl = opts.sourceControl ?? this; + this._forEachChild((control) => { + control.markAsUntouched({ + onlySelf: true, + emitEvent: opts.emitEvent, + sourceControl + }); + }); + if (this._parent && !opts.onlySelf) { + this._parent._updateTouched(opts, sourceControl); + } + if (changed && opts.emitEvent !== false) { + this._events.next(new TouchedChangeEvent(false, sourceControl)); + } + } + markAsDirty(opts = {}) { + const changed = this.pristine === true; + this.pristine = false; + const sourceControl = opts.sourceControl ?? this; + if (this._parent && !opts.onlySelf) { + this._parent.markAsDirty(__spreadProps(__spreadValues({}, opts), { + sourceControl + })); + } + if (changed && opts.emitEvent !== false) { + this._events.next(new PristineChangeEvent(false, sourceControl)); + } + } + markAsPristine(opts = {}) { + const changed = this.pristine === false; + this.pristine = true; + this._pendingDirty = false; + const sourceControl = opts.sourceControl ?? this; + this._forEachChild((control) => { + control.markAsPristine({ + onlySelf: true, + emitEvent: opts.emitEvent + }); + }); + if (this._parent && !opts.onlySelf) { + this._parent._updatePristine(opts, sourceControl); + } + if (changed && opts.emitEvent !== false) { + this._events.next(new PristineChangeEvent(true, sourceControl)); + } + } + markAsPending(opts = {}) { + this.status = PENDING; + const sourceControl = opts.sourceControl ?? this; + if (opts.emitEvent !== false) { + this._events.next(new StatusChangeEvent(this.status, sourceControl)); + this.statusChanges.emit(this.status); + } + if (this._parent && !opts.onlySelf) { + this._parent.markAsPending(__spreadProps(__spreadValues({}, opts), { + sourceControl + })); + } + } + disable(opts = {}) { + const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf); + this.status = DISABLED; + this.errors = null; + this._forEachChild((control) => { + control.disable(__spreadProps(__spreadValues({}, opts), { + onlySelf: true + })); + }); + this._updateValue(); + const sourceControl = opts.sourceControl ?? this; + if (opts.emitEvent !== false) { + this._events.next(new ValueChangeEvent(this.value, sourceControl)); + this._events.next(new StatusChangeEvent(this.status, sourceControl)); + this.valueChanges.emit(this.value); + this.statusChanges.emit(this.status); + } + this._updateAncestors(__spreadProps(__spreadValues({}, opts), { + skipPristineCheck + }), this); + this._onDisabledChange.forEach((changeFn) => changeFn(true)); + } + /** + * Enables the control. This means the control is included in validation checks and + * the aggregate value of its parent. Its status recalculates based on its value and + * its validators. + * + * By default, if the control has children, all children are enabled. + * + * @see {@link AbstractControl.status} + * + * @param opts Configure options that control how the control propagates changes and + * emits events when marked as untouched + * * `onlySelf`: When true, mark only this control. When false or not supplied, + * marks all direct ancestors. Default is false. + * * `emitEvent`: When true or not supplied (the default), the `statusChanges`, + * `valueChanges` and `events` + * observables emit events with the latest status and value when the control is enabled. + * When false, no events are emitted. + */ + enable(opts = {}) { + const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf); + this.status = VALID; + this._forEachChild((control) => { + control.enable(__spreadProps(__spreadValues({}, opts), { + onlySelf: true + })); + }); + this.updateValueAndValidity({ + onlySelf: true, + emitEvent: opts.emitEvent + }); + this._updateAncestors(__spreadProps(__spreadValues({}, opts), { + skipPristineCheck + }), this); + this._onDisabledChange.forEach((changeFn) => changeFn(false)); + } + _updateAncestors(opts, sourceControl) { + if (this._parent && !opts.onlySelf) { + this._parent.updateValueAndValidity(opts); + if (!opts.skipPristineCheck) { + this._parent._updatePristine({}, sourceControl); + } + this._parent._updateTouched({}, sourceControl); + } + } + /** + * Sets the parent of the control + * + * @param parent The new parent. + */ + setParent(parent) { + this._parent = parent; + } + /** + * The raw value of this control. For most control implementations, the raw value will include + * disabled children. + */ + getRawValue() { + return this.value; + } + updateValueAndValidity(opts = {}) { + this._setInitialStatus(); + this._updateValue(); + if (this.enabled) { + const shouldHaveEmitted = this._cancelExistingSubscription(); + this.errors = this._runValidator(); + this.status = this._calculateStatus(); + if (this.status === VALID || this.status === PENDING) { + this._runAsyncValidator(shouldHaveEmitted, opts.emitEvent); + } + } + const sourceControl = opts.sourceControl ?? this; + if (opts.emitEvent !== false) { + this._events.next(new ValueChangeEvent(this.value, sourceControl)); + this._events.next(new StatusChangeEvent(this.status, sourceControl)); + this.valueChanges.emit(this.value); + this.statusChanges.emit(this.status); + } + if (this._parent && !opts.onlySelf) { + this._parent.updateValueAndValidity(__spreadProps(__spreadValues({}, opts), { + sourceControl + })); + } + } + /** @internal */ + _updateTreeValidity(opts = { + emitEvent: true + }) { + this._forEachChild((ctrl) => ctrl._updateTreeValidity(opts)); + this.updateValueAndValidity({ + onlySelf: true, + emitEvent: opts.emitEvent + }); + } + _setInitialStatus() { + this.status = this._allControlsDisabled() ? DISABLED : VALID; + } + _runValidator() { + return this.validator ? this.validator(this) : null; + } + _runAsyncValidator(shouldHaveEmitted, emitEvent) { + if (this.asyncValidator) { + this.status = PENDING; + this._hasOwnPendingAsyncValidator = { + emitEvent: emitEvent !== false, + shouldHaveEmitted: shouldHaveEmitted !== false + }; + const obs = toObservable(this.asyncValidator(this)); + this._asyncValidationSubscription = obs.subscribe((errors) => { + this._hasOwnPendingAsyncValidator = null; + this.setErrors(errors, { + emitEvent, + shouldHaveEmitted + }); + }); + } + } + _cancelExistingSubscription() { + if (this._asyncValidationSubscription) { + this._asyncValidationSubscription.unsubscribe(); + const shouldHaveEmitted = (this._hasOwnPendingAsyncValidator?.emitEvent || this._hasOwnPendingAsyncValidator?.shouldHaveEmitted) ?? false; + this._hasOwnPendingAsyncValidator = null; + return shouldHaveEmitted; + } + return false; + } + setErrors(errors, opts = {}) { + this.errors = errors; + this._updateControlsErrors(opts.emitEvent !== false, this, opts.shouldHaveEmitted); + } + /** + * Retrieves a child control given the control's name or path. + * + * @param path A dot-delimited string or array of string/number values that define the path to the + * control. If a string is provided, passing it as a string literal will result in improved type + * information. Likewise, if an array is provided, passing it `as const` will cause improved type + * information to be available. + * + * @usageNotes + * ### Retrieve a nested control + * + * For example, to get a `name` control nested within a `person` sub-group: + * + * * `this.form.get('person.name');` + * + * -OR- + * + * * `this.form.get(['person', 'name'] as const);` // `as const` gives improved typings + * + * ### Retrieve a control in a FormArray + * + * When accessing an element inside a FormArray, you can use an element index. + * For example, to get a `price` control from the first element in an `items` array you can use: + * + * * `this.form.get('items.0.price');` + * + * -OR- + * + * * `this.form.get(['items', 0, 'price']);` + */ + get(path) { + let currPath = path; + if (currPath == null) return null; + if (!Array.isArray(currPath)) currPath = currPath.split("."); + if (currPath.length === 0) return null; + return currPath.reduce((control, name) => control && control._find(name), this); + } + /** + * @description + * Reports error data for the control with the given path. + * + * @param errorCode The code of the error to check + * @param path A list of control names that designates how to move from the current control + * to the control that should be queried for errors. + * + * @usageNotes + * For example, for the following `FormGroup`: + * + * ```ts + * form = new FormGroup({ + * address: new FormGroup({ street: new FormControl() }) + * }); + * ``` + * + * The path to the 'street' control from the root form would be 'address' -> 'street'. + * + * It can be provided to this method in one of two formats: + * + * 1. An array of string control names, e.g. `['address', 'street']` + * 1. A period-delimited list of control names in one string, e.g. `'address.street'` + * + * @returns error data for that particular error. If the control or error is not present, + * null is returned. + */ + getError(errorCode, path) { + const control = path ? this.get(path) : this; + return control && control.errors ? control.errors[errorCode] : null; + } + /** + * @description + * Reports whether the control with the given path has the error specified. + * + * @param errorCode The code of the error to check + * @param path A list of control names that designates how to move from the current control + * to the control that should be queried for errors. + * + * @usageNotes + * For example, for the following `FormGroup`: + * + * ```ts + * form = new FormGroup({ + * address: new FormGroup({ street: new FormControl() }) + * }); + * ``` + * + * The path to the 'street' control from the root form would be 'address' -> 'street'. + * + * It can be provided to this method in one of two formats: + * + * 1. An array of string control names, e.g. `['address', 'street']` + * 1. A period-delimited list of control names in one string, e.g. `'address.street'` + * + * If no path is given, this method checks for the error on the current control. + * + * @returns whether the given error is present in the control at the given path. + * + * If the control is not present, false is returned. + */ + hasError(errorCode, path) { + return !!this.getError(errorCode, path); + } + /** + * Retrieves the top-level ancestor of this control. + */ + get root() { + let x = this; + while (x._parent) { + x = x._parent; + } + return x; + } + /** @internal */ + _updateControlsErrors(emitEvent, changedControl, shouldHaveEmitted) { + this.status = this._calculateStatus(); + if (emitEvent) { + this.statusChanges.emit(this.status); + } + if (emitEvent || shouldHaveEmitted) { + this._events.next(new StatusChangeEvent(this.status, changedControl)); + } + if (this._parent) { + this._parent._updateControlsErrors(emitEvent, changedControl, shouldHaveEmitted); + } + } + /** @internal */ + _initObservables() { + this.valueChanges = new EventEmitter(); + this.statusChanges = new EventEmitter(); + } + _calculateStatus() { + if (this._allControlsDisabled()) return DISABLED; + if (this.errors) return INVALID; + if (this._hasOwnPendingAsyncValidator || this._anyControlsHaveStatus(PENDING)) return PENDING; + if (this._anyControlsHaveStatus(INVALID)) return INVALID; + return VALID; + } + /** @internal */ + _anyControlsHaveStatus(status) { + return this._anyControls((control) => control.status === status); + } + /** @internal */ + _anyControlsDirty() { + return this._anyControls((control) => control.dirty); + } + /** @internal */ + _anyControlsTouched() { + return this._anyControls((control) => control.touched); + } + /** @internal */ + _updatePristine(opts, changedControl) { + const newPristine = !this._anyControlsDirty(); + const changed = this.pristine !== newPristine; + this.pristine = newPristine; + if (this._parent && !opts.onlySelf) { + this._parent._updatePristine(opts, changedControl); + } + if (changed) { + this._events.next(new PristineChangeEvent(this.pristine, changedControl)); + } + } + /** @internal */ + _updateTouched(opts = {}, changedControl) { + this.touched = this._anyControlsTouched(); + this._events.next(new TouchedChangeEvent(this.touched, changedControl)); + if (this._parent && !opts.onlySelf) { + this._parent._updateTouched(opts, changedControl); + } + } + /** @internal */ + _onDisabledChange = []; + /** @internal */ + _registerOnCollectionChange(fn) { + this._onCollectionChange = fn; + } + /** @internal */ + _setUpdateStrategy(opts) { + if (isOptionsObj(opts) && opts.updateOn != null) { + this._updateOn = opts.updateOn; + } + } + /** + * Check to see if parent has been marked artificially dirty. + * + * @internal + */ + _parentMarkedDirty(onlySelf) { + const parentDirty = this._parent && this._parent.dirty; + return !onlySelf && !!parentDirty && !this._parent._anyControlsDirty(); + } + /** @internal */ + _find(name) { + return null; + } + /** + * Internal implementation of the `setValidators` method. Needs to be separated out into a + * different method, because it is called in the constructor and it can break cases where + * a control is extended. + */ + _assignValidators(validators) { + this._rawValidators = Array.isArray(validators) ? validators.slice() : validators; + this._composedValidatorFn = coerceToValidator(this._rawValidators); + } + /** + * Internal implementation of the `setAsyncValidators` method. Needs to be separated out into a + * different method, because it is called in the constructor and it can break cases where + * a control is extended. + */ + _assignAsyncValidators(validators) { + this._rawAsyncValidators = Array.isArray(validators) ? validators.slice() : validators; + this._composedAsyncValidatorFn = coerceToAsyncValidator(this._rawAsyncValidators); + } +}; +var FormGroup = class extends AbstractControl { + /** + * Creates a new `FormGroup` instance. + * + * @param controls A collection of child controls. The key for each child is the name + * under which it is registered. + * + * @param validatorOrOpts A synchronous validator function, or an array of + * such functions, or an `AbstractControlOptions` object that contains validation functions + * and a validation trigger. + * + * @param asyncValidator A single async validator or array of async validator functions + * + */ + constructor(controls, validatorOrOpts, asyncValidator) { + super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts)); + (typeof ngDevMode === "undefined" || ngDevMode) && validateFormGroupControls(controls); + this.controls = controls; + this._initObservables(); + this._setUpdateStrategy(validatorOrOpts); + this._setUpControls(); + this.updateValueAndValidity({ + onlySelf: true, + // If `asyncValidator` is present, it will trigger control status change from `PENDING` to + // `VALID` or `INVALID`. The status should be broadcasted via the `statusChanges` observable, + // so we set `emitEvent` to `true` to allow that during the control creation process. + emitEvent: !!this.asyncValidator + }); + } + controls; + registerControl(name, control) { + if (this.controls[name]) return this.controls[name]; + this.controls[name] = control; + control.setParent(this); + control._registerOnCollectionChange(this._onCollectionChange); + return control; + } + addControl(name, control, options = {}) { + this.registerControl(name, control); + this.updateValueAndValidity({ + emitEvent: options.emitEvent + }); + this._onCollectionChange(); + } + /** + * Remove a control from this group. In a strongly-typed group, required controls cannot be + * removed. + * + * This method also updates the value and validity of the control. + * + * @param name The control name to remove from the collection + * @param options Specifies whether this FormGroup instance should emit events after a + * control is removed. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` observables emit events with the latest status and value when the control is + * removed. When false, no events are emitted. + */ + removeControl(name, options = {}) { + if (this.controls[name]) this.controls[name]._registerOnCollectionChange(() => { + }); + delete this.controls[name]; + this.updateValueAndValidity({ + emitEvent: options.emitEvent + }); + this._onCollectionChange(); + } + setControl(name, control, options = {}) { + if (this.controls[name]) this.controls[name]._registerOnCollectionChange(() => { + }); + delete this.controls[name]; + if (control) this.registerControl(name, control); + this.updateValueAndValidity({ + emitEvent: options.emitEvent + }); + this._onCollectionChange(); + } + contains(controlName) { + return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled; + } + /** + * Sets the value of the `FormGroup`. It accepts an object that matches + * the structure of the group, with control names as keys. + * + * @usageNotes + * ### Set the complete value for the form group + * + * ```ts + * const form = new FormGroup({ + * first: new FormControl(), + * last: new FormControl() + * }); + * + * console.log(form.value); // {first: null, last: null} + * + * form.setValue({first: 'Nancy', last: 'Drew'}); + * console.log(form.value); // {first: 'Nancy', last: 'Drew'} + * ``` + * + * @throws When strict checks fail, such as setting the value of a control + * that doesn't exist or if you exclude a value of a control that does exist. + * + * @param value The new value for the control that matches the structure of the group. + * @param options Configuration options that determine how the control propagates changes + * and emits events after the value changes. + * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity + * updateValueAndValidity} method. + * + * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is + * false. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` + * observables emit events with the latest status and value when the control value is updated. + * When false, no events are emitted. + */ + setValue(value, options = {}) { + assertAllValuesPresent(this, true, value); + Object.keys(value).forEach((name) => { + assertControlPresent(this, true, name); + this.controls[name].setValue(value[name], { + onlySelf: true, + emitEvent: options.emitEvent + }); + }); + this.updateValueAndValidity(options); + } + /** + * Patches the value of the `FormGroup`. It accepts an object with control + * names as keys, and does its best to match the values to the correct controls + * in the group. + * + * It accepts both super-sets and sub-sets of the group without throwing an error. + * + * @usageNotes + * ### Patch the value for a form group + * + * ```ts + * const form = new FormGroup({ + * first: new FormControl(), + * last: new FormControl() + * }); + * console.log(form.value); // {first: null, last: null} + * + * form.patchValue({first: 'Nancy'}); + * console.log(form.value); // {first: 'Nancy', last: null} + * ``` + * + * @param value The object that matches the structure of the group. + * @param options Configuration options that determine how the control propagates changes and + * emits events after the value is patched. + * * `onlySelf`: When true, each change only affects this control and not its parent. Default is + * true. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` observables emit events with the latest status and value when the control value + * is updated. When false, no events are emitted. The configuration options are passed to + * the {@link AbstractControl#updateValueAndValidity updateValueAndValidity} method. + */ + patchValue(value, options = {}) { + if (value == null) return; + Object.keys(value).forEach((name) => { + const control = this.controls[name]; + if (control) { + control.patchValue( + /* Guaranteed to be present, due to the outer forEach. */ + value[name], + { + onlySelf: true, + emitEvent: options.emitEvent + } + ); + } + }); + this.updateValueAndValidity(options); + } + /** + * Resets the `FormGroup`, marks all descendants `pristine` and `untouched` and sets + * the value of all descendants to their default values, or null if no defaults were provided. + * + * You reset to a specific form state by passing in a map of states + * that matches the structure of your form, with control names as keys. The state + * is a standalone value or a form state object with both a value and a disabled + * status. + * + * @param value Resets the control with an initial value, + * or an object that defines the initial value and disabled state. + * + * @param options Configuration options that determine how the control propagates changes + * and emits events when the group is reset. + * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is + * false. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` + * observables emit events with the latest status and value when the control is reset. + * When false, no events are emitted. + * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity + * updateValueAndValidity} method. + * + * @usageNotes + * + * ### Reset the form group values + * + * ```ts + * const form = new FormGroup({ + * first: new FormControl('first name'), + * last: new FormControl('last name') + * }); + * + * console.log(form.value); // {first: 'first name', last: 'last name'} + * + * form.reset({ first: 'name', last: 'last name' }); + * + * console.log(form.value); // {first: 'name', last: 'last name'} + * ``` + * + * ### Reset the form group values and disabled status + * + * ```ts + * const form = new FormGroup({ + * first: new FormControl('first name'), + * last: new FormControl('last name') + * }); + * + * form.reset({ + * first: {value: 'name', disabled: true}, + * last: 'last' + * }); + * + * console.log(form.value); // {last: 'last'} + * console.log(form.get('first').status); // 'DISABLED' + * ``` + */ + reset(value = {}, options = {}) { + this._forEachChild((control, name) => { + control.reset(value ? value[name] : null, { + onlySelf: true, + emitEvent: options.emitEvent + }); + }); + this._updatePristine(options, this); + this._updateTouched(options, this); + this.updateValueAndValidity(options); + } + /** + * The aggregate value of the `FormGroup`, including any disabled controls. + * + * Retrieves all values regardless of disabled status. + */ + getRawValue() { + return this._reduceChildren({}, (acc, control, name) => { + acc[name] = control.getRawValue(); + return acc; + }); + } + /** @internal */ + _syncPendingControls() { + let subtreeUpdated = this._reduceChildren(false, (updated, child) => { + return child._syncPendingControls() ? true : updated; + }); + if (subtreeUpdated) this.updateValueAndValidity({ + onlySelf: true + }); + return subtreeUpdated; + } + /** @internal */ + _forEachChild(cb) { + Object.keys(this.controls).forEach((key) => { + const control = this.controls[key]; + control && cb(control, key); + }); + } + /** @internal */ + _setUpControls() { + this._forEachChild((control) => { + control.setParent(this); + control._registerOnCollectionChange(this._onCollectionChange); + }); + } + /** @internal */ + _updateValue() { + this.value = this._reduceValue(); + } + /** @internal */ + _anyControls(condition) { + for (const [controlName, control] of Object.entries(this.controls)) { + if (this.contains(controlName) && condition(control)) { + return true; + } + } + return false; + } + /** @internal */ + _reduceValue() { + let acc = {}; + return this._reduceChildren(acc, (acc2, control, name) => { + if (control.enabled || this.disabled) { + acc2[name] = control.value; + } + return acc2; + }); + } + /** @internal */ + _reduceChildren(initValue, fn) { + let res = initValue; + this._forEachChild((control, name) => { + res = fn(res, control, name); + }); + return res; + } + /** @internal */ + _allControlsDisabled() { + for (const controlName of Object.keys(this.controls)) { + if (this.controls[controlName].enabled) { + return false; + } + } + return Object.keys(this.controls).length > 0 || this.disabled; + } + /** @internal */ + _find(name) { + return this.controls.hasOwnProperty(name) ? this.controls[name] : null; + } +}; +function validateFormGroupControls(controls) { + const invalidKeys = Object.keys(controls).filter((key) => key.includes(".")); + if (invalidKeys.length > 0) { + console.warn(`FormGroup keys cannot include \`.\`, please replace the keys for: ${invalidKeys.join(",")}.`); + } +} +var UntypedFormGroup = FormGroup; +var isFormGroup = (control) => control instanceof FormGroup; +var FormRecord = class extends FormGroup { +}; +var isFormRecord = (control) => control instanceof FormRecord; +var CALL_SET_DISABLED_STATE = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "CallSetDisabledState" : "", { + providedIn: "root", + factory: () => setDisabledStateDefault +}); +var setDisabledStateDefault = "always"; +function controlPath(name, parent) { + return [...parent.path, name]; +} +function setUpControl(control, dir, callSetDisabledState = setDisabledStateDefault) { + if (typeof ngDevMode === "undefined" || ngDevMode) { + if (!control) _throwError(dir, "Cannot find control with"); + if (!dir.valueAccessor) _throwMissingValueAccessorError(dir); + } + setUpValidators(control, dir); + dir.valueAccessor.writeValue(control.value); + if (control.disabled || callSetDisabledState === "always") { + dir.valueAccessor.setDisabledState?.(control.disabled); + } + setUpViewChangePipeline(control, dir); + setUpModelChangePipeline(control, dir); + setUpBlurPipeline(control, dir); + setUpDisabledChangeHandler(control, dir); +} +function cleanUpControl(control, dir, validateControlPresenceOnChange = true) { + const noop = () => { + if (validateControlPresenceOnChange && (typeof ngDevMode === "undefined" || ngDevMode)) { + _noControlError(dir); + } + }; + if (dir.valueAccessor) { + dir.valueAccessor.registerOnChange(noop); + dir.valueAccessor.registerOnTouched(noop); + } + cleanUpValidators(control, dir); + if (control) { + dir._invokeOnDestroyCallbacks(); + control._registerOnCollectionChange(() => { + }); + } +} +function registerOnValidatorChange(validators, onChange) { + validators.forEach((validator) => { + if (validator.registerOnValidatorChange) validator.registerOnValidatorChange(onChange); + }); +} +function setUpDisabledChangeHandler(control, dir) { + if (dir.valueAccessor.setDisabledState) { + const onDisabledChange = (isDisabled) => { + dir.valueAccessor.setDisabledState(isDisabled); + }; + control.registerOnDisabledChange(onDisabledChange); + dir._registerOnDestroy(() => { + control._unregisterOnDisabledChange(onDisabledChange); + }); + } +} +function setUpValidators(control, dir) { + const validators = getControlValidators(control); + if (dir.validator !== null) { + control.setValidators(mergeValidators(validators, dir.validator)); + } else if (typeof validators === "function") { + control.setValidators([validators]); + } + const asyncValidators = getControlAsyncValidators(control); + if (dir.asyncValidator !== null) { + control.setAsyncValidators(mergeValidators(asyncValidators, dir.asyncValidator)); + } else if (typeof asyncValidators === "function") { + control.setAsyncValidators([asyncValidators]); + } + const onValidatorChange = () => control.updateValueAndValidity(); + registerOnValidatorChange(dir._rawValidators, onValidatorChange); + registerOnValidatorChange(dir._rawAsyncValidators, onValidatorChange); +} +function cleanUpValidators(control, dir) { + let isControlUpdated = false; + if (control !== null) { + if (dir.validator !== null) { + const validators = getControlValidators(control); + if (Array.isArray(validators) && validators.length > 0) { + const updatedValidators = validators.filter((validator) => validator !== dir.validator); + if (updatedValidators.length !== validators.length) { + isControlUpdated = true; + control.setValidators(updatedValidators); + } + } + } + if (dir.asyncValidator !== null) { + const asyncValidators = getControlAsyncValidators(control); + if (Array.isArray(asyncValidators) && asyncValidators.length > 0) { + const updatedAsyncValidators = asyncValidators.filter((asyncValidator) => asyncValidator !== dir.asyncValidator); + if (updatedAsyncValidators.length !== asyncValidators.length) { + isControlUpdated = true; + control.setAsyncValidators(updatedAsyncValidators); + } + } + } + } + const noop = () => { + }; + registerOnValidatorChange(dir._rawValidators, noop); + registerOnValidatorChange(dir._rawAsyncValidators, noop); + return isControlUpdated; +} +function setUpViewChangePipeline(control, dir) { + dir.valueAccessor.registerOnChange((newValue) => { + control._pendingValue = newValue; + control._pendingChange = true; + control._pendingDirty = true; + if (control.updateOn === "change") updateControl(control, dir); + }); +} +function setUpBlurPipeline(control, dir) { + dir.valueAccessor.registerOnTouched(() => { + control._pendingTouched = true; + if (control.updateOn === "blur" && control._pendingChange) updateControl(control, dir); + if (control.updateOn !== "submit") control.markAsTouched(); + }); +} +function updateControl(control, dir) { + if (control._pendingDirty) control.markAsDirty(); + control.setValue(control._pendingValue, { + emitModelToViewChange: false + }); + dir.viewToModelUpdate(control._pendingValue); + control._pendingChange = false; +} +function setUpModelChangePipeline(control, dir) { + const onChange = (newValue, emitModelEvent) => { + dir.valueAccessor.writeValue(newValue); + if (emitModelEvent) dir.viewToModelUpdate(newValue); + }; + control.registerOnChange(onChange); + dir._registerOnDestroy(() => { + control._unregisterOnChange(onChange); + }); +} +function setUpFormContainer(control, dir) { + if (control == null && (typeof ngDevMode === "undefined" || ngDevMode)) _throwError(dir, "Cannot find control with"); + setUpValidators(control, dir); +} +function cleanUpFormContainer(control, dir) { + return cleanUpValidators(control, dir); +} +function _noControlError(dir) { + return _throwError(dir, "There is no FormControl instance attached to form control element with"); +} +function _throwError(dir, message) { + const messageEnd = _describeControlLocation(dir); + throw new Error(`${message} ${messageEnd}`); +} +function _describeControlLocation(dir) { + const path = dir.path; + if (path && path.length > 1) return `path: '${path.join(" -> ")}'`; + if (path?.[0]) return `name: '${path}'`; + return "unspecified name attribute"; +} +function _throwMissingValueAccessorError(dir) { + const loc = _describeControlLocation(dir); + throw new RuntimeError(-1203, `No value accessor for form control ${loc}.`); +} +function _throwInvalidValueAccessorError(dir) { + const loc = _describeControlLocation(dir); + throw new RuntimeError(1200, `Value accessor was not provided as an array for form control with ${loc}. Check that the \`NG_VALUE_ACCESSOR\` token is configured as a \`multi: true\` provider.`); +} +function isPropertyUpdated(changes, viewModel) { + if (!changes.hasOwnProperty("model")) return false; + const change = changes["model"]; + if (change.isFirstChange()) return true; + return !Object.is(viewModel, change.currentValue); +} +function isBuiltInAccessor(valueAccessor) { + return Object.getPrototypeOf(valueAccessor.constructor) === BuiltInControlValueAccessor; +} +function syncPendingControls(form, directives) { + form._syncPendingControls(); + directives.forEach((dir) => { + const control = dir.control; + if (control.updateOn === "submit" && control._pendingChange) { + dir.viewToModelUpdate(control._pendingValue); + control._pendingChange = false; + } + }); +} +function selectValueAccessor(dir, valueAccessors) { + if (!valueAccessors) return null; + if (!Array.isArray(valueAccessors) && (typeof ngDevMode === "undefined" || ngDevMode)) _throwInvalidValueAccessorError(dir); + let defaultAccessor = void 0; + let builtinAccessor = void 0; + let customAccessor = void 0; + valueAccessors.forEach((v) => { + if (v.constructor === DefaultValueAccessor) { + defaultAccessor = v; + } else if (isBuiltInAccessor(v)) { + if (builtinAccessor && (typeof ngDevMode === "undefined" || ngDevMode)) _throwError(dir, "More than one built-in value accessor matches form control with"); + builtinAccessor = v; + } else { + if (customAccessor && (typeof ngDevMode === "undefined" || ngDevMode)) _throwError(dir, "More than one custom value accessor matches form control with"); + customAccessor = v; + } + }); + if (customAccessor) return customAccessor; + if (builtinAccessor) return builtinAccessor; + if (defaultAccessor) return defaultAccessor; + if (typeof ngDevMode === "undefined" || ngDevMode) { + _throwError(dir, "No valid value accessor for form control with"); + } + return null; +} +function removeListItem$1(list, el) { + const index = list.indexOf(el); + if (index > -1) list.splice(index, 1); +} +function _ngModelWarning(name, type, instance, warningConfig) { + if (warningConfig === "never") return; + if ((warningConfig === null || warningConfig === "once") && !type._ngModelWarningSentOnce || warningConfig === "always" && !instance._ngModelWarningSent) { + console.warn(ngModelWarning(name)); + type._ngModelWarningSentOnce = true; + instance._ngModelWarningSent = true; + } +} +var formDirectiveProvider$1 = { + provide: ControlContainer, + useExisting: forwardRef(() => NgForm) +}; +var resolvedPromise$1 = (() => Promise.resolve())(); +var NgForm = class _NgForm extends ControlContainer { + callSetDisabledState; + /** + * @description + * Returns whether the form submission has been triggered. + */ + get submitted() { + return untracked(this.submittedReactive); + } + /** @internal */ + _submitted = computed(() => this.submittedReactive(), ...ngDevMode ? [{ + debugName: "_submitted" + }] : []); + submittedReactive = signal(false, ...ngDevMode ? [{ + debugName: "submittedReactive" + }] : []); + _directives = /* @__PURE__ */ new Set(); + /** + * @description + * The `FormGroup` instance created for this form. + */ + form; + /** + * @description + * Event emitter for the "ngSubmit" event + */ + ngSubmit = new EventEmitter(); + /** + * @description + * Tracks options for the `NgForm` instance. + * + * **updateOn**: Sets the default `updateOn` value for all child `NgModels` below it + * unless explicitly set by a child `NgModel` using `ngModelOptions`). Defaults to 'change'. + * Possible values: `'change'` | `'blur'` | `'submit'`. + * + */ + options; + constructor(validators, asyncValidators, callSetDisabledState) { + super(); + this.callSetDisabledState = callSetDisabledState; + this.form = new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators)); + } + /** @docs-private */ + ngAfterViewInit() { + this._setUpdateStrategy(); + } + /** + * @description + * The directive instance. + */ + get formDirective() { + return this; + } + /** + * @description + * The internal `FormGroup` instance. + */ + get control() { + return this.form; + } + /** + * @description + * Returns an array representing the path to this group. Because this directive + * always lives at the top level of a form, it is always an empty array. + */ + get path() { + return []; + } + /** + * @description + * Returns a map of the controls in this group. + */ + get controls() { + return this.form.controls; + } + /** + * @description + * Method that sets up the control directive in this group, re-calculates its value + * and validity, and adds the instance to the internal list of directives. + * + * @param dir The `NgModel` directive instance. + */ + addControl(dir) { + resolvedPromise$1.then(() => { + const container = this._findContainer(dir.path); + dir.control = container.registerControl(dir.name, dir.control); + setUpControl(dir.control, dir, this.callSetDisabledState); + dir.control.updateValueAndValidity({ + emitEvent: false + }); + this._directives.add(dir); + }); + } + /** + * @description + * Retrieves the `FormControl` instance from the provided `NgModel` directive. + * + * @param dir The `NgModel` directive instance. + */ + getControl(dir) { + return this.form.get(dir.path); + } + /** + * @description + * Removes the `NgModel` instance from the internal list of directives + * + * @param dir The `NgModel` directive instance. + */ + removeControl(dir) { + resolvedPromise$1.then(() => { + const container = this._findContainer(dir.path); + if (container) { + container.removeControl(dir.name); + } + this._directives.delete(dir); + }); + } + /** + * @description + * Adds a new `NgModelGroup` directive instance to the form. + * + * @param dir The `NgModelGroup` directive instance. + */ + addFormGroup(dir) { + resolvedPromise$1.then(() => { + const container = this._findContainer(dir.path); + const group = new FormGroup({}); + setUpFormContainer(group, dir); + container.registerControl(dir.name, group); + group.updateValueAndValidity({ + emitEvent: false + }); + }); + } + /** + * @description + * Removes the `NgModelGroup` directive instance from the form. + * + * @param dir The `NgModelGroup` directive instance. + */ + removeFormGroup(dir) { + resolvedPromise$1.then(() => { + const container = this._findContainer(dir.path); + if (container) { + container.removeControl(dir.name); + } + }); + } + /** + * @description + * Retrieves the `FormGroup` for a provided `NgModelGroup` directive instance + * + * @param dir The `NgModelGroup` directive instance. + */ + getFormGroup(dir) { + return this.form.get(dir.path); + } + /** + * Sets the new value for the provided `NgControl` directive. + * + * @param dir The `NgControl` directive instance. + * @param value The new value for the directive's control. + */ + updateModel(dir, value) { + resolvedPromise$1.then(() => { + const ctrl = this.form.get(dir.path); + ctrl.setValue(value); + }); + } + /** + * @description + * Sets the value for this `FormGroup`. + * + * @param value The new value + */ + setValue(value) { + this.control.setValue(value); + } + /** + * @description + * Method called when the "submit" event is triggered on the form. + * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload. + * + * @param $event The "submit" event object + */ + onSubmit($event) { + this.submittedReactive.set(true); + syncPendingControls(this.form, this._directives); + this.ngSubmit.emit($event); + this.form._events.next(new FormSubmittedEvent(this.control)); + return $event?.target?.method === "dialog"; + } + /** + * @description + * Method called when the "reset" event is triggered on the form. + */ + onReset() { + this.resetForm(); + } + /** + * @description + * Resets the form to an initial value and resets its submitted status. + * + * @param value The new value for the form. + */ + resetForm(value = void 0) { + this.form.reset(value); + this.submittedReactive.set(false); + this.form._events.next(new FormResetEvent(this.form)); + } + _setUpdateStrategy() { + if (this.options && this.options.updateOn != null) { + this.form._updateOn = this.options.updateOn; + } + } + _findContainer(path) { + path.pop(); + return path.length ? this.form.get(path) : this.form; + } + static ɵfac = function NgForm_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _NgForm)(ɵɵdirectiveInject(NG_VALIDATORS, 10), ɵɵdirectiveInject(NG_ASYNC_VALIDATORS, 10), ɵɵdirectiveInject(CALL_SET_DISABLED_STATE, 8)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _NgForm, + selectors: [["form", 3, "ngNoForm", "", 3, "formGroup", ""], ["ng-form"], ["", "ngForm", ""]], + hostBindings: function NgForm_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("submit", function NgForm_submit_HostBindingHandler($event) { + return ctx.onSubmit($event); + })("reset", function NgForm_reset_HostBindingHandler() { + return ctx.onReset(); + }); + } + }, + inputs: { + options: [0, "ngFormOptions", "options"] + }, + outputs: { + ngSubmit: "ngSubmit" + }, + exportAs: ["ngForm"], + standalone: false, + features: [ɵɵProvidersFeature([formDirectiveProvider$1]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgForm, [{ + type: Directive, + args: [{ + selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", + providers: [formDirectiveProvider$1], + host: { + "(submit)": "onSubmit($event)", + "(reset)": "onReset()" + }, + outputs: ["ngSubmit"], + exportAs: "ngForm", + standalone: false + }] + }], () => [{ + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_ASYNC_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Inject, + args: [CALL_SET_DISABLED_STATE] + }] + }], { + options: [{ + type: Input, + args: ["ngFormOptions"] + }] + }); +})(); +function removeListItem(list, el) { + const index = list.indexOf(el); + if (index > -1) list.splice(index, 1); +} +function isFormControlState(formState) { + return typeof formState === "object" && formState !== null && Object.keys(formState).length === 2 && "value" in formState && "disabled" in formState; +} +var FormControl = class FormControl2 extends AbstractControl { + /** @publicApi */ + defaultValue = null; + /** @internal */ + _onChange = []; + /** @internal */ + _pendingValue; + /** @internal */ + _pendingChange = false; + constructor(formState = null, validatorOrOpts, asyncValidator) { + super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts)); + this._applyFormState(formState); + this._setUpdateStrategy(validatorOrOpts); + this._initObservables(); + this.updateValueAndValidity({ + onlySelf: true, + // If `asyncValidator` is present, it will trigger control status change from `PENDING` to + // `VALID` or `INVALID`. + // The status should be broadcasted via the `statusChanges` observable, so we set + // `emitEvent` to `true` to allow that during the control creation process. + emitEvent: !!this.asyncValidator + }); + if (isOptionsObj(validatorOrOpts) && (validatorOrOpts.nonNullable || validatorOrOpts.initialValueIsDefault)) { + if (isFormControlState(formState)) { + this.defaultValue = formState.value; + } else { + this.defaultValue = formState; + } + } + } + setValue(value, options = {}) { + this.value = this._pendingValue = value; + if (this._onChange.length && options.emitModelToViewChange !== false) { + this._onChange.forEach((changeFn) => changeFn(this.value, options.emitViewToModelChange !== false)); + } + this.updateValueAndValidity(options); + } + patchValue(value, options = {}) { + this.setValue(value, options); + } + reset(formState = this.defaultValue, options = {}) { + this._applyFormState(formState); + this.markAsPristine(options); + this.markAsUntouched(options); + this.setValue(this.value, options); + this._pendingChange = false; + } + /** @internal */ + _updateValue() { + } + /** @internal */ + _anyControls(condition) { + return false; + } + /** @internal */ + _allControlsDisabled() { + return this.disabled; + } + registerOnChange(fn) { + this._onChange.push(fn); + } + /** @internal */ + _unregisterOnChange(fn) { + removeListItem(this._onChange, fn); + } + registerOnDisabledChange(fn) { + this._onDisabledChange.push(fn); + } + /** @internal */ + _unregisterOnDisabledChange(fn) { + removeListItem(this._onDisabledChange, fn); + } + /** @internal */ + _forEachChild(cb) { + } + /** @internal */ + _syncPendingControls() { + if (this.updateOn === "submit") { + if (this._pendingDirty) this.markAsDirty(); + if (this._pendingTouched) this.markAsTouched(); + if (this._pendingChange) { + this.setValue(this._pendingValue, { + onlySelf: true, + emitModelToViewChange: false + }); + return true; + } + } + return false; + } + _applyFormState(formState) { + if (isFormControlState(formState)) { + this.value = this._pendingValue = formState.value; + formState.disabled ? this.disable({ + onlySelf: true, + emitEvent: false + }) : this.enable({ + onlySelf: true, + emitEvent: false + }); + } else { + this.value = this._pendingValue = formState; + } + } +}; +var UntypedFormControl = FormControl; +var isFormControl = (control) => control instanceof FormControl; +var AbstractFormGroupDirective = class _AbstractFormGroupDirective extends ControlContainer { + /** + * @description + * The parent control for the group + * + * @internal + */ + _parent; + /** @docs-private */ + ngOnInit() { + this._checkParentType(); + this.formDirective.addFormGroup(this); + } + /** @docs-private */ + ngOnDestroy() { + if (this.formDirective) { + this.formDirective.removeFormGroup(this); + } + } + /** + * @description + * The `FormGroup` bound to this directive. + */ + get control() { + return this.formDirective.getFormGroup(this); + } + /** + * @description + * The path to this group from the top-level directive. + */ + get path() { + return controlPath(this.name == null ? this.name : this.name.toString(), this._parent); + } + /** + * @description + * The top-level directive for this group if present, otherwise null. + */ + get formDirective() { + return this._parent ? this._parent.formDirective : null; + } + /** @internal */ + _checkParentType() { + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵAbstractFormGroupDirective_BaseFactory; + return function AbstractFormGroupDirective_Factory(__ngFactoryType__) { + return (ɵAbstractFormGroupDirective_BaseFactory || (ɵAbstractFormGroupDirective_BaseFactory = ɵɵgetInheritedFactory(_AbstractFormGroupDirective)))(__ngFactoryType__ || _AbstractFormGroupDirective); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _AbstractFormGroupDirective, + standalone: false, + features: [ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(AbstractFormGroupDirective, [{ + type: Directive, + args: [{ + standalone: false + }] + }], null, null); +})(); +function modelParentException() { + return new RuntimeError(1350, ` + ngModel cannot be used to register form controls with a parent formGroup directive. Try using + formGroup's partner directive "formControlName" instead. Example: + + ${formControlNameExample} + + Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions: + + Example: + + ${ngModelWithFormGroupExample}`); +} +function formGroupNameException() { + return new RuntimeError(1351, ` + ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive. + + Option 1: Use formControlName instead of ngModel (reactive strategy): + + ${formGroupNameExample} + + Option 2: Update ngModel's parent be ngModelGroup (template-driven strategy): + + ${ngModelGroupExample}`); +} +function missingNameException() { + return new RuntimeError(1352, `If ngModel is used within a form tag, either the name attribute must be set or the form + control must be defined as 'standalone' in ngModelOptions. + + Example 1: + Example 2: `); +} +function modelGroupParentException() { + return new RuntimeError(1353, ` + ngModelGroup cannot be used with a parent formGroup directive. + + Option 1: Use formGroupName instead of ngModelGroup (reactive strategy): + + ${formGroupNameExample} + + Option 2: Use a regular form tag instead of the formGroup directive (template-driven strategy): + + ${ngModelGroupExample}`); +} +var modelGroupProvider = { + provide: ControlContainer, + useExisting: forwardRef(() => NgModelGroup) +}; +var NgModelGroup = class _NgModelGroup extends AbstractFormGroupDirective { + /** + * @description + * Tracks the name of the `NgModelGroup` bound to the directive. The name corresponds + * to a key in the parent `NgForm`. + */ + name = ""; + constructor(parent, validators, asyncValidators) { + super(); + this._parent = parent; + this._setValidators(validators); + this._setAsyncValidators(asyncValidators); + } + /** @internal */ + _checkParentType() { + if (!(this._parent instanceof _NgModelGroup) && !(this._parent instanceof NgForm) && (typeof ngDevMode === "undefined" || ngDevMode)) { + throw modelGroupParentException(); + } + } + static ɵfac = function NgModelGroup_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _NgModelGroup)(ɵɵdirectiveInject(ControlContainer, 5), ɵɵdirectiveInject(NG_VALIDATORS, 10), ɵɵdirectiveInject(NG_ASYNC_VALIDATORS, 10)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _NgModelGroup, + selectors: [["", "ngModelGroup", ""]], + inputs: { + name: [0, "ngModelGroup", "name"] + }, + exportAs: ["ngModelGroup"], + standalone: false, + features: [ɵɵProvidersFeature([modelGroupProvider]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgModelGroup, [{ + type: Directive, + args: [{ + selector: "[ngModelGroup]", + providers: [modelGroupProvider], + exportAs: "ngModelGroup", + standalone: false + }] + }], () => [{ + type: ControlContainer, + decorators: [{ + type: Host + }, { + type: SkipSelf + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_ASYNC_VALIDATORS] + }] + }], { + name: [{ + type: Input, + args: ["ngModelGroup"] + }] + }); +})(); +var formControlBinding$1 = { + provide: NgControl, + useExisting: forwardRef(() => NgModel) +}; +var resolvedPromise = (() => Promise.resolve())(); +var NgModel = class _NgModel extends NgControl { + _changeDetectorRef; + callSetDisabledState; + control = new FormControl(); + // At runtime we coerce arbitrary values assigned to the "disabled" input to a "boolean". + // This is not reflected in the type of the property because outside of templates, consumers + // should only deal with booleans. In templates, a string is allowed for convenience and to + // match the native "disabled attribute" semantics which can be observed on input elements. + // This static member tells the compiler that values of type "string" can also be assigned + // to the input in a template. + /** @docs-private */ + static ngAcceptInputType_isDisabled; + /** @internal */ + _registered = false; + /** + * Internal reference to the view model value. + * @docs-private + */ + viewModel; + /** + * @description + * Tracks the name bound to the directive. If a parent form exists, it + * uses this name as a key to retrieve this control's value. + */ + name = ""; + /** + * @description + * Tracks whether the control is disabled. + */ + isDisabled; + /** + * @description + * Tracks the value bound to this directive. + */ + model; + /** + * @description + * Tracks the configuration options for this `ngModel` instance. + * + * **name**: An alternative to setting the name attribute on the form control element. See + * the [example](api/forms/NgModel#using-ngmodel-on-a-standalone-control) for using `NgModel` + * as a standalone control. + * + * **standalone**: When set to true, the `ngModel` will not register itself with its parent form, + * and acts as if it's not in the form. Defaults to false. If no parent form exists, this option + * has no effect. + * + * **updateOn**: Defines the event upon which the form control value and validity update. + * Defaults to 'change'. Possible values: `'change'` | `'blur'` | `'submit'`. + * + */ + options; + /** + * @description + * Event emitter for producing the `ngModelChange` event after + * the view model updates. + */ + update = new EventEmitter(); + constructor(parent, validators, asyncValidators, valueAccessors, _changeDetectorRef, callSetDisabledState) { + super(); + this._changeDetectorRef = _changeDetectorRef; + this.callSetDisabledState = callSetDisabledState; + this._parent = parent; + this._setValidators(validators); + this._setAsyncValidators(asyncValidators); + this.valueAccessor = selectValueAccessor(this, valueAccessors); + } + /** @docs-private */ + ngOnChanges(changes) { + this._checkForErrors(); + if (!this._registered || "name" in changes) { + if (this._registered) { + this._checkName(); + if (this.formDirective) { + const oldName = changes["name"].previousValue; + this.formDirective.removeControl({ + name: oldName, + path: this._getPath(oldName) + }); + } + } + this._setUpControl(); + } + if ("isDisabled" in changes) { + this._updateDisabled(changes); + } + if (isPropertyUpdated(changes, this.viewModel)) { + this._updateValue(this.model); + this.viewModel = this.model; + } + } + /** @docs-private */ + ngOnDestroy() { + this.formDirective && this.formDirective.removeControl(this); + } + /** + * @description + * Returns an array that represents the path from the top-level form to this control. + * Each index is the string name of the control on that level. + */ + get path() { + return this._getPath(this.name); + } + /** + * @description + * The top-level directive for this control if present, otherwise null. + */ + get formDirective() { + return this._parent ? this._parent.formDirective : null; + } + /** + * @description + * Sets the new value for the view model and emits an `ngModelChange` event. + * + * @param newValue The new value emitted by `ngModelChange`. + */ + viewToModelUpdate(newValue) { + this.viewModel = newValue; + this.update.emit(newValue); + } + _setUpControl() { + this._setUpdateStrategy(); + this._isStandalone() ? this._setUpStandalone() : this.formDirective.addControl(this); + this._registered = true; + } + _setUpdateStrategy() { + if (this.options && this.options.updateOn != null) { + this.control._updateOn = this.options.updateOn; + } + } + _isStandalone() { + return !this._parent || !!(this.options && this.options.standalone); + } + _setUpStandalone() { + setUpControl(this.control, this, this.callSetDisabledState); + this.control.updateValueAndValidity({ + emitEvent: false + }); + } + _checkForErrors() { + if ((typeof ngDevMode === "undefined" || ngDevMode) && !this._isStandalone()) { + checkParentType$1(this._parent); + } + this._checkName(); + } + _checkName() { + if (this.options && this.options.name) this.name = this.options.name; + if (!this._isStandalone() && !this.name && (typeof ngDevMode === "undefined" || ngDevMode)) { + throw missingNameException(); + } + } + _updateValue(value) { + resolvedPromise.then(() => { + this.control.setValue(value, { + emitViewToModelChange: false + }); + this._changeDetectorRef?.markForCheck(); + }); + } + _updateDisabled(changes) { + const disabledValue = changes["isDisabled"].currentValue; + const isDisabled = disabledValue !== 0 && booleanAttribute(disabledValue); + resolvedPromise.then(() => { + if (isDisabled && !this.control.disabled) { + this.control.disable(); + } else if (!isDisabled && this.control.disabled) { + this.control.enable(); + } + this._changeDetectorRef?.markForCheck(); + }); + } + _getPath(controlName) { + return this._parent ? controlPath(controlName, this._parent) : [controlName]; + } + static ɵfac = function NgModel_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _NgModel)(ɵɵdirectiveInject(ControlContainer, 9), ɵɵdirectiveInject(NG_VALIDATORS, 10), ɵɵdirectiveInject(NG_ASYNC_VALIDATORS, 10), ɵɵdirectiveInject(NG_VALUE_ACCESSOR, 10), ɵɵdirectiveInject(ChangeDetectorRef, 8), ɵɵdirectiveInject(CALL_SET_DISABLED_STATE, 8)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _NgModel, + selectors: [["", "ngModel", "", 3, "formControlName", "", 3, "formControl", ""]], + inputs: { + name: "name", + isDisabled: [0, "disabled", "isDisabled"], + model: [0, "ngModel", "model"], + options: [0, "ngModelOptions", "options"] + }, + outputs: { + update: "ngModelChange" + }, + exportAs: ["ngModel"], + standalone: false, + features: [ɵɵProvidersFeature([formControlBinding$1]), ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgModel, [{ + type: Directive, + args: [{ + selector: "[ngModel]:not([formControlName]):not([formControl])", + providers: [formControlBinding$1], + exportAs: "ngModel", + standalone: false + }] + }], () => [{ + type: ControlContainer, + decorators: [{ + type: Optional + }, { + type: Host + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_ASYNC_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALUE_ACCESSOR] + }] + }, { + type: ChangeDetectorRef, + decorators: [{ + type: Optional + }, { + type: Inject, + args: [ChangeDetectorRef] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Inject, + args: [CALL_SET_DISABLED_STATE] + }] + }], { + name: [{ + type: Input + }], + isDisabled: [{ + type: Input, + args: ["disabled"] + }], + model: [{ + type: Input, + args: ["ngModel"] + }], + options: [{ + type: Input, + args: ["ngModelOptions"] + }], + update: [{ + type: Output, + args: ["ngModelChange"] + }] + }); +})(); +function checkParentType$1(parent) { + if (!(parent instanceof NgModelGroup) && parent instanceof AbstractFormGroupDirective) { + throw formGroupNameException(); + } else if (!(parent instanceof NgModelGroup) && !(parent instanceof NgForm)) { + throw modelParentException(); + } +} +var ɵNgNoValidate = class _ɵNgNoValidate { + static ɵfac = function ɵNgNoValidate_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _ɵNgNoValidate)(); + }; + static ɵdir = ɵɵdefineDirective({ + type: _ɵNgNoValidate, + selectors: [["form", 3, "ngNoForm", "", 3, "ngNativeValidate", ""]], + hostAttrs: ["novalidate", ""], + standalone: false + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ɵNgNoValidate, [{ + type: Directive, + args: [{ + selector: "form:not([ngNoForm]):not([ngNativeValidate])", + host: { + "novalidate": "" + }, + standalone: false + }] + }], null, null); +})(); +var NUMBER_VALUE_ACCESSOR = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => NumberValueAccessor), + multi: true +}; +var NumberValueAccessor = class _NumberValueAccessor extends BuiltInControlValueAccessor { + /** + * Sets the "value" property on the input element. + * @docs-private + */ + writeValue(value) { + const normalizedValue = value == null ? "" : value; + this.setProperty("value", normalizedValue); + } + /** + * Registers a function called when the control value changes. + * @docs-private + */ + registerOnChange(fn) { + this.onChange = (value) => { + fn(value == "" ? null : parseFloat(value)); + }; + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵNumberValueAccessor_BaseFactory; + return function NumberValueAccessor_Factory(__ngFactoryType__) { + return (ɵNumberValueAccessor_BaseFactory || (ɵNumberValueAccessor_BaseFactory = ɵɵgetInheritedFactory(_NumberValueAccessor)))(__ngFactoryType__ || _NumberValueAccessor); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _NumberValueAccessor, + selectors: [["input", "type", "number", "formControlName", ""], ["input", "type", "number", "formControl", ""], ["input", "type", "number", "ngModel", ""]], + hostBindings: function NumberValueAccessor_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("input", function NumberValueAccessor_input_HostBindingHandler($event) { + return ctx.onChange($event.target.value); + })("blur", function NumberValueAccessor_blur_HostBindingHandler() { + return ctx.onTouched(); + }); + } + }, + standalone: false, + features: [ɵɵProvidersFeature([NUMBER_VALUE_ACCESSOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NumberValueAccessor, [{ + type: Directive, + args: [{ + selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]", + host: { + "(input)": "onChange($any($event.target).value)", + "(blur)": "onTouched()" + }, + providers: [NUMBER_VALUE_ACCESSOR], + standalone: false + }] + }], null, null); +})(); +var RADIO_VALUE_ACCESSOR = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => RadioControlValueAccessor), + multi: true +}; +function throwNameError() { + throw new RuntimeError(1202, ` + If you define both a name and a formControlName attribute on your radio button, their values + must match. Ex: + `); +} +var RadioControlRegistry = class _RadioControlRegistry { + _accessors = []; + /** + * @description + * Adds a control to the internal registry. For internal use only. + */ + add(control, accessor) { + this._accessors.push([control, accessor]); + } + /** + * @description + * Removes a control from the internal registry. For internal use only. + */ + remove(accessor) { + for (let i = this._accessors.length - 1; i >= 0; --i) { + if (this._accessors[i][1] === accessor) { + this._accessors.splice(i, 1); + return; + } + } + } + /** + * @description + * Selects a radio button. For internal use only. + */ + select(accessor) { + this._accessors.forEach((c) => { + if (this._isSameGroup(c, accessor) && c[1] !== accessor) { + c[1].fireUncheck(accessor.value); + } + }); + } + _isSameGroup(controlPair, accessor) { + if (!controlPair[0].control) return false; + return controlPair[0]._parent === accessor._control._parent && controlPair[1].name === accessor.name; + } + static ɵfac = function RadioControlRegistry_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _RadioControlRegistry)(); + }; + static ɵprov = ɵɵdefineInjectable({ + token: _RadioControlRegistry, + factory: _RadioControlRegistry.ɵfac, + providedIn: "root" + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RadioControlRegistry, [{ + type: Injectable, + args: [{ + providedIn: "root" + }] + }], null, null); +})(); +var RadioControlValueAccessor = class _RadioControlValueAccessor extends BuiltInControlValueAccessor { + _registry; + _injector; + /** @internal */ + _state; + /** @internal */ + _control; + /** @internal */ + _fn; + setDisabledStateFired = false; + /** + * The registered callback function called when a change event occurs on the input element. + * Note: we declare `onChange` here (also used as host listener) as a function with no arguments + * to override the `onChange` function (which expects 1 argument) in the parent + * `BaseControlValueAccessor` class. + * @docs-private + */ + onChange = () => { + }; + /** + * @description + * Tracks the name of the radio input element. + */ + name; + /** + * @description + * Tracks the name of the `FormControl` bound to the directive. The name corresponds + * to a key in the parent `FormGroup` or `FormArray`. + */ + formControlName; + /** + * @description + * Tracks the value of the radio input element + */ + value; + callSetDisabledState = inject(CALL_SET_DISABLED_STATE, { + optional: true + }) ?? setDisabledStateDefault; + constructor(renderer, elementRef, _registry, _injector) { + super(renderer, elementRef); + this._registry = _registry; + this._injector = _injector; + } + /** @docs-private */ + ngOnInit() { + this._control = this._injector.get(NgControl); + this._checkName(); + this._registry.add(this._control, this); + } + /** @docs-private */ + ngOnDestroy() { + this._registry.remove(this); + } + /** + * Sets the "checked" property value on the radio input element. + * @docs-private + */ + writeValue(value) { + this._state = value === this.value; + this.setProperty("checked", this._state); + } + /** + * Registers a function called when the control value changes. + * @docs-private + */ + registerOnChange(fn) { + this._fn = fn; + this.onChange = () => { + fn(this.value); + this._registry.select(this); + }; + } + /** @docs-private */ + setDisabledState(isDisabled) { + if (this.setDisabledStateFired || isDisabled || this.callSetDisabledState === "whenDisabledForLegacyCode") { + this.setProperty("disabled", isDisabled); + } + this.setDisabledStateFired = true; + } + /** + * Sets the "value" on the radio input element and unchecks it. + * + * @param value + */ + fireUncheck(value) { + this.writeValue(value); + } + _checkName() { + if (this.name && this.formControlName && this.name !== this.formControlName && (typeof ngDevMode === "undefined" || ngDevMode)) { + throwNameError(); + } + if (!this.name && this.formControlName) this.name = this.formControlName; + } + static ɵfac = function RadioControlValueAccessor_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _RadioControlValueAccessor)(ɵɵdirectiveInject(Renderer2), ɵɵdirectiveInject(ElementRef), ɵɵdirectiveInject(RadioControlRegistry), ɵɵdirectiveInject(Injector)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _RadioControlValueAccessor, + selectors: [["input", "type", "radio", "formControlName", ""], ["input", "type", "radio", "formControl", ""], ["input", "type", "radio", "ngModel", ""]], + hostBindings: function RadioControlValueAccessor_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("change", function RadioControlValueAccessor_change_HostBindingHandler() { + return ctx.onChange(); + })("blur", function RadioControlValueAccessor_blur_HostBindingHandler() { + return ctx.onTouched(); + }); + } + }, + inputs: { + name: "name", + formControlName: "formControlName", + value: "value" + }, + standalone: false, + features: [ɵɵProvidersFeature([RADIO_VALUE_ACCESSOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RadioControlValueAccessor, [{ + type: Directive, + args: [{ + selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", + host: { + "(change)": "onChange()", + "(blur)": "onTouched()" + }, + providers: [RADIO_VALUE_ACCESSOR], + standalone: false + }] + }], () => [{ + type: Renderer2 + }, { + type: ElementRef + }, { + type: RadioControlRegistry + }, { + type: Injector + }], { + name: [{ + type: Input + }], + formControlName: [{ + type: Input + }], + value: [{ + type: Input + }] + }); +})(); +var RANGE_VALUE_ACCESSOR = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => RangeValueAccessor), + multi: true +}; +var RangeValueAccessor = class _RangeValueAccessor extends BuiltInControlValueAccessor { + /** + * Sets the "value" property on the input element. + * @docs-private + */ + writeValue(value) { + this.setProperty("value", parseFloat(value)); + } + /** + * Registers a function called when the control value changes. + * @docs-private + */ + registerOnChange(fn) { + this.onChange = (value) => { + fn(value == "" ? null : parseFloat(value)); + }; + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵRangeValueAccessor_BaseFactory; + return function RangeValueAccessor_Factory(__ngFactoryType__) { + return (ɵRangeValueAccessor_BaseFactory || (ɵRangeValueAccessor_BaseFactory = ɵɵgetInheritedFactory(_RangeValueAccessor)))(__ngFactoryType__ || _RangeValueAccessor); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _RangeValueAccessor, + selectors: [["input", "type", "range", "formControlName", ""], ["input", "type", "range", "formControl", ""], ["input", "type", "range", "ngModel", ""]], + hostBindings: function RangeValueAccessor_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("change", function RangeValueAccessor_change_HostBindingHandler($event) { + return ctx.onChange($event.target.value); + })("input", function RangeValueAccessor_input_HostBindingHandler($event) { + return ctx.onChange($event.target.value); + })("blur", function RangeValueAccessor_blur_HostBindingHandler() { + return ctx.onTouched(); + }); + } + }, + standalone: false, + features: [ɵɵProvidersFeature([RANGE_VALUE_ACCESSOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RangeValueAccessor, [{ + type: Directive, + args: [{ + selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]", + host: { + "(change)": "onChange($any($event.target).value)", + "(input)": "onChange($any($event.target).value)", + "(blur)": "onTouched()" + }, + providers: [RANGE_VALUE_ACCESSOR], + standalone: false + }] + }], null, null); +})(); +var NG_MODEL_WITH_FORM_CONTROL_WARNING = new InjectionToken(ngDevMode ? "NgModelWithFormControlWarning" : ""); +var formControlBinding = { + provide: NgControl, + useExisting: forwardRef(() => FormControlDirective) +}; +var FormControlDirective = class _FormControlDirective extends NgControl { + _ngModelWarningConfig; + callSetDisabledState; + /** + * Internal reference to the view model value. + * @docs-private + */ + viewModel; + /** + * @description + * Tracks the `FormControl` instance bound to the directive. + */ + form; + /** + * @description + * Triggers a warning in dev mode that this input should not be used with reactive forms. + */ + set isDisabled(isDisabled) { + if (typeof ngDevMode === "undefined" || ngDevMode) { + console.warn(disabledAttrWarning); + } + } + // TODO(kara): remove next 4 properties once deprecation period is over + /** @deprecated as of v6 */ + model; + /** @deprecated as of v6 */ + update = new EventEmitter(); + /** + * @description + * Static property used to track whether any ngModel warnings have been sent across + * all instances of FormControlDirective. Used to support warning config of "once". + * + * @internal + */ + static _ngModelWarningSentOnce = false; + /** + * @description + * Instance property used to track whether an ngModel warning has been sent out for this + * particular `FormControlDirective` instance. Used to support warning config of "always". + * + * @internal + */ + _ngModelWarningSent = false; + constructor(validators, asyncValidators, valueAccessors, _ngModelWarningConfig, callSetDisabledState) { + super(); + this._ngModelWarningConfig = _ngModelWarningConfig; + this.callSetDisabledState = callSetDisabledState; + this._setValidators(validators); + this._setAsyncValidators(asyncValidators); + this.valueAccessor = selectValueAccessor(this, valueAccessors); + } + /** @docs-private */ + ngOnChanges(changes) { + if (this._isControlChanged(changes)) { + const previousForm = changes["form"].previousValue; + if (previousForm) { + cleanUpControl( + previousForm, + this, + /* validateControlPresenceOnChange */ + false + ); + } + setUpControl(this.form, this, this.callSetDisabledState); + this.form.updateValueAndValidity({ + emitEvent: false + }); + } + if (isPropertyUpdated(changes, this.viewModel)) { + if (typeof ngDevMode === "undefined" || ngDevMode) { + _ngModelWarning("formControl", _FormControlDirective, this, this._ngModelWarningConfig); + } + this.form.setValue(this.model); + this.viewModel = this.model; + } + } + /** @docs-private */ + ngOnDestroy() { + if (this.form) { + cleanUpControl( + this.form, + this, + /* validateControlPresenceOnChange */ + false + ); + } + } + /** + * @description + * Returns an array that represents the path from the top-level form to this control. + * Each index is the string name of the control on that level. + */ + get path() { + return []; + } + /** + * @description + * The `FormControl` bound to this directive. + */ + get control() { + return this.form; + } + /** + * @description + * Sets the new value for the view model and emits an `ngModelChange` event. + * + * @param newValue The new value for the view model. + */ + viewToModelUpdate(newValue) { + this.viewModel = newValue; + this.update.emit(newValue); + } + _isControlChanged(changes) { + return changes.hasOwnProperty("form"); + } + static ɵfac = function FormControlDirective_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _FormControlDirective)(ɵɵdirectiveInject(NG_VALIDATORS, 10), ɵɵdirectiveInject(NG_ASYNC_VALIDATORS, 10), ɵɵdirectiveInject(NG_VALUE_ACCESSOR, 10), ɵɵdirectiveInject(NG_MODEL_WITH_FORM_CONTROL_WARNING, 8), ɵɵdirectiveInject(CALL_SET_DISABLED_STATE, 8)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _FormControlDirective, + selectors: [["", "formControl", ""]], + inputs: { + form: [0, "formControl", "form"], + isDisabled: [0, "disabled", "isDisabled"], + model: [0, "ngModel", "model"] + }, + outputs: { + update: "ngModelChange" + }, + exportAs: ["ngForm"], + standalone: false, + features: [ɵɵProvidersFeature([formControlBinding]), ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(FormControlDirective, [{ + type: Directive, + args: [{ + selector: "[formControl]", + providers: [formControlBinding], + exportAs: "ngForm", + standalone: false + }] + }], () => [{ + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_ASYNC_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALUE_ACCESSOR] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Inject, + args: [NG_MODEL_WITH_FORM_CONTROL_WARNING] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Inject, + args: [CALL_SET_DISABLED_STATE] + }] + }], { + form: [{ + type: Input, + args: ["formControl"] + }], + isDisabled: [{ + type: Input, + args: ["disabled"] + }], + model: [{ + type: Input, + args: ["ngModel"] + }], + update: [{ + type: Output, + args: ["ngModelChange"] + }] + }); +})(); +var formDirectiveProvider = { + provide: ControlContainer, + useExisting: forwardRef(() => FormGroupDirective) +}; +var FormGroupDirective = class _FormGroupDirective extends ControlContainer { + callSetDisabledState; + /** + * @description + * Reports whether the form submission has been triggered. + */ + get submitted() { + return untracked(this._submittedReactive); + } + // TODO(atscott): Remove once invalid API usage is cleaned up internally + set submitted(value) { + this._submittedReactive.set(value); + } + /** @internal */ + _submitted = computed(() => this._submittedReactive(), ...ngDevMode ? [{ + debugName: "_submitted" + }] : []); + _submittedReactive = signal(false, ...ngDevMode ? [{ + debugName: "_submittedReactive" + }] : []); + /** + * Reference to an old form group input value, which is needed to cleanup + * old instance in case it was replaced with a new one. + */ + _oldForm; + /** + * Callback that should be invoked when controls in FormGroup or FormArray collection change + * (added or removed). This callback triggers corresponding DOM updates. + */ + _onCollectionChange = () => this._updateDomValue(); + /** + * @description + * Tracks the list of added `FormControlName` instances + */ + directives = []; + /** + * @description + * Tracks the `FormGroup` bound to this directive. + */ + form = null; + /** + * @description + * Emits an event when the form submission has been triggered. + */ + ngSubmit = new EventEmitter(); + constructor(validators, asyncValidators, callSetDisabledState) { + super(); + this.callSetDisabledState = callSetDisabledState; + this._setValidators(validators); + this._setAsyncValidators(asyncValidators); + } + /** @docs-private */ + ngOnChanges(changes) { + if ((typeof ngDevMode === "undefined" || ngDevMode) && !this.form) { + throw missingFormException(); + } + if (changes.hasOwnProperty("form")) { + this._updateValidators(); + this._updateDomValue(); + this._updateRegistrations(); + this._oldForm = this.form; + } + } + /** @docs-private */ + ngOnDestroy() { + if (this.form) { + cleanUpValidators(this.form, this); + if (this.form._onCollectionChange === this._onCollectionChange) { + this.form._registerOnCollectionChange(() => { + }); + } + } + } + /** + * @description + * Returns this directive's instance. + */ + get formDirective() { + return this; + } + /** + * @description + * Returns the `FormGroup` bound to this directive. + */ + get control() { + return this.form; + } + /** + * @description + * Returns an array representing the path to this group. Because this directive + * always lives at the top level of a form, it always an empty array. + */ + get path() { + return []; + } + /** + * @description + * Method that sets up the control directive in this group, re-calculates its value + * and validity, and adds the instance to the internal list of directives. + * + * @param dir The `FormControlName` directive instance. + */ + addControl(dir) { + const ctrl = this.form.get(dir.path); + setUpControl(ctrl, dir, this.callSetDisabledState); + ctrl.updateValueAndValidity({ + emitEvent: false + }); + this.directives.push(dir); + return ctrl; + } + /** + * @description + * Retrieves the `FormControl` instance from the provided `FormControlName` directive + * + * @param dir The `FormControlName` directive instance. + */ + getControl(dir) { + return this.form.get(dir.path); + } + /** + * @description + * Removes the `FormControlName` instance from the internal list of directives + * + * @param dir The `FormControlName` directive instance. + */ + removeControl(dir) { + cleanUpControl( + dir.control || null, + dir, + /* validateControlPresenceOnChange */ + false + ); + removeListItem$1(this.directives, dir); + } + /** + * Adds a new `FormGroupName` directive instance to the form. + * + * @param dir The `FormGroupName` directive instance. + */ + addFormGroup(dir) { + this._setUpFormContainer(dir); + } + /** + * Performs the necessary cleanup when a `FormGroupName` directive instance is removed from the + * view. + * + * @param dir The `FormGroupName` directive instance. + */ + removeFormGroup(dir) { + this._cleanUpFormContainer(dir); + } + /** + * @description + * Retrieves the `FormGroup` for a provided `FormGroupName` directive instance + * + * @param dir The `FormGroupName` directive instance. + */ + getFormGroup(dir) { + return this.form.get(dir.path); + } + /** + * Performs the necessary setup when a `FormArrayName` directive instance is added to the view. + * + * @param dir The `FormArrayName` directive instance. + */ + addFormArray(dir) { + this._setUpFormContainer(dir); + } + /** + * Performs the necessary cleanup when a `FormArrayName` directive instance is removed from the + * view. + * + * @param dir The `FormArrayName` directive instance. + */ + removeFormArray(dir) { + this._cleanUpFormContainer(dir); + } + /** + * @description + * Retrieves the `FormArray` for a provided `FormArrayName` directive instance. + * + * @param dir The `FormArrayName` directive instance. + */ + getFormArray(dir) { + return this.form.get(dir.path); + } + /** + * Sets the new value for the provided `FormControlName` directive. + * + * @param dir The `FormControlName` directive instance. + * @param value The new value for the directive's control. + */ + updateModel(dir, value) { + const ctrl = this.form.get(dir.path); + ctrl.setValue(value); + } + /** + * @description + * Method called with the "submit" event is triggered on the form. + * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload. + * + * @param $event The "submit" event object + */ + onSubmit($event) { + this._submittedReactive.set(true); + syncPendingControls(this.form, this.directives); + this.ngSubmit.emit($event); + this.form._events.next(new FormSubmittedEvent(this.control)); + return $event?.target?.method === "dialog"; + } + /** + * @description + * Method called when the "reset" event is triggered on the form. + */ + onReset() { + this.resetForm(); + } + /** + * @description + * Resets the form to an initial value and resets its submitted status. + * + * @param value The new value for the form, `undefined` by default + */ + resetForm(value = void 0, options = {}) { + this.form.reset(value, options); + this._submittedReactive.set(false); + if (options?.emitEvent !== false) { + this.form._events.next(new FormResetEvent(this.form)); + } + } + /** @internal */ + _updateDomValue() { + this.directives.forEach((dir) => { + const oldCtrl = dir.control; + const newCtrl = this.form.get(dir.path); + if (oldCtrl !== newCtrl) { + cleanUpControl(oldCtrl || null, dir); + if (isFormControl(newCtrl)) { + setUpControl(newCtrl, dir, this.callSetDisabledState); + dir.control = newCtrl; + } + } + }); + this.form._updateTreeValidity({ + emitEvent: false + }); + } + _setUpFormContainer(dir) { + const ctrl = this.form.get(dir.path); + setUpFormContainer(ctrl, dir); + ctrl.updateValueAndValidity({ + emitEvent: false + }); + } + _cleanUpFormContainer(dir) { + if (this.form) { + const ctrl = this.form.get(dir.path); + if (ctrl) { + const isControlUpdated = cleanUpFormContainer(ctrl, dir); + if (isControlUpdated) { + ctrl.updateValueAndValidity({ + emitEvent: false + }); + } + } + } + } + _updateRegistrations() { + this.form._registerOnCollectionChange(this._onCollectionChange); + if (this._oldForm) { + this._oldForm._registerOnCollectionChange(() => { + }); + } + } + _updateValidators() { + setUpValidators(this.form, this); + if (this._oldForm) { + cleanUpValidators(this._oldForm, this); + } + } + static ɵfac = function FormGroupDirective_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _FormGroupDirective)(ɵɵdirectiveInject(NG_VALIDATORS, 10), ɵɵdirectiveInject(NG_ASYNC_VALIDATORS, 10), ɵɵdirectiveInject(CALL_SET_DISABLED_STATE, 8)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _FormGroupDirective, + selectors: [["", "formGroup", ""]], + hostBindings: function FormGroupDirective_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("submit", function FormGroupDirective_submit_HostBindingHandler($event) { + return ctx.onSubmit($event); + })("reset", function FormGroupDirective_reset_HostBindingHandler() { + return ctx.onReset(); + }); + } + }, + inputs: { + form: [0, "formGroup", "form"] + }, + outputs: { + ngSubmit: "ngSubmit" + }, + exportAs: ["ngForm"], + standalone: false, + features: [ɵɵProvidersFeature([formDirectiveProvider]), ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(FormGroupDirective, [{ + type: Directive, + args: [{ + selector: "[formGroup]", + providers: [formDirectiveProvider], + host: { + "(submit)": "onSubmit($event)", + "(reset)": "onReset()" + }, + exportAs: "ngForm", + standalone: false + }] + }], () => [{ + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_ASYNC_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Inject, + args: [CALL_SET_DISABLED_STATE] + }] + }], { + form: [{ + type: Input, + args: ["formGroup"] + }], + ngSubmit: [{ + type: Output + }] + }); +})(); +var formGroupNameProvider = { + provide: ControlContainer, + useExisting: forwardRef(() => FormGroupName) +}; +var FormGroupName = class _FormGroupName extends AbstractFormGroupDirective { + /** + * @description + * Tracks the name of the `FormGroup` bound to the directive. The name corresponds + * to a key in the parent `FormGroup` or `FormArray`. + * Accepts a name as a string or a number. + * The name in the form of a string is useful for individual forms, + * while the numerical form allows for form groups to be bound + * to indices when iterating over groups in a `FormArray`. + */ + name = null; + constructor(parent, validators, asyncValidators) { + super(); + this._parent = parent; + this._setValidators(validators); + this._setAsyncValidators(asyncValidators); + } + /** @internal */ + _checkParentType() { + if (hasInvalidParent(this._parent) && (typeof ngDevMode === "undefined" || ngDevMode)) { + throw groupParentException(); + } + } + static ɵfac = function FormGroupName_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _FormGroupName)(ɵɵdirectiveInject(ControlContainer, 13), ɵɵdirectiveInject(NG_VALIDATORS, 10), ɵɵdirectiveInject(NG_ASYNC_VALIDATORS, 10)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _FormGroupName, + selectors: [["", "formGroupName", ""]], + inputs: { + name: [0, "formGroupName", "name"] + }, + standalone: false, + features: [ɵɵProvidersFeature([formGroupNameProvider]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(FormGroupName, [{ + type: Directive, + args: [{ + selector: "[formGroupName]", + providers: [formGroupNameProvider], + standalone: false + }] + }], () => [{ + type: ControlContainer, + decorators: [{ + type: Optional + }, { + type: Host + }, { + type: SkipSelf + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_ASYNC_VALIDATORS] + }] + }], { + name: [{ + type: Input, + args: ["formGroupName"] + }] + }); +})(); +var formArrayNameProvider = { + provide: ControlContainer, + useExisting: forwardRef(() => FormArrayName) +}; +var FormArrayName = class _FormArrayName extends ControlContainer { + /** @internal */ + _parent; + /** + * @description + * Tracks the name of the `FormArray` bound to the directive. The name corresponds + * to a key in the parent `FormGroup` or `FormArray`. + * Accepts a name as a string or a number. + * The name in the form of a string is useful for individual forms, + * while the numerical form allows for form arrays to be bound + * to indices when iterating over arrays in a `FormArray`. + */ + name = null; + constructor(parent, validators, asyncValidators) { + super(); + this._parent = parent; + this._setValidators(validators); + this._setAsyncValidators(asyncValidators); + } + /** + * A lifecycle method called when the directive's inputs are initialized. For internal use only. + * @throws If the directive does not have a valid parent. + * @docs-private + */ + ngOnInit() { + if (hasInvalidParent(this._parent) && (typeof ngDevMode === "undefined" || ngDevMode)) { + throw arrayParentException(); + } + this.formDirective.addFormArray(this); + } + /** + * A lifecycle method called before the directive's instance is destroyed. For internal use only. + * @docs-private + */ + ngOnDestroy() { + this.formDirective?.removeFormArray(this); + } + /** + * @description + * The `FormArray` bound to this directive. + */ + get control() { + return this.formDirective.getFormArray(this); + } + /** + * @description + * The top-level directive for this group if present, otherwise null. + */ + get formDirective() { + return this._parent ? this._parent.formDirective : null; + } + /** + * @description + * Returns an array that represents the path from the top-level form to this control. + * Each index is the string name of the control on that level. + */ + get path() { + return controlPath(this.name == null ? this.name : this.name.toString(), this._parent); + } + static ɵfac = function FormArrayName_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _FormArrayName)(ɵɵdirectiveInject(ControlContainer, 13), ɵɵdirectiveInject(NG_VALIDATORS, 10), ɵɵdirectiveInject(NG_ASYNC_VALIDATORS, 10)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _FormArrayName, + selectors: [["", "formArrayName", ""]], + inputs: { + name: [0, "formArrayName", "name"] + }, + standalone: false, + features: [ɵɵProvidersFeature([formArrayNameProvider]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(FormArrayName, [{ + type: Directive, + args: [{ + selector: "[formArrayName]", + providers: [formArrayNameProvider], + standalone: false + }] + }], () => [{ + type: ControlContainer, + decorators: [{ + type: Optional + }, { + type: Host + }, { + type: SkipSelf + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_ASYNC_VALIDATORS] + }] + }], { + name: [{ + type: Input, + args: ["formArrayName"] + }] + }); +})(); +function hasInvalidParent(parent) { + return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) && !(parent instanceof FormArrayName); +} +var controlNameBinding = { + provide: NgControl, + useExisting: forwardRef(() => FormControlName) +}; +var FormControlName = class _FormControlName extends NgControl { + _ngModelWarningConfig; + _added = false; + /** + * Internal reference to the view model value. + * @internal + */ + viewModel; + /** + * @description + * Tracks the `FormControl` instance bound to the directive. + */ + control; + /** + * @description + * Tracks the name of the `FormControl` bound to the directive. The name corresponds + * to a key in the parent `FormGroup` or `FormArray`. + * Accepts a name as a string or a number. + * The name in the form of a string is useful for individual forms, + * while the numerical form allows for form controls to be bound + * to indices when iterating over controls in a `FormArray`. + */ + name = null; + /** + * @description + * Triggers a warning in dev mode that this input should not be used with reactive forms. + */ + set isDisabled(isDisabled) { + if (typeof ngDevMode === "undefined" || ngDevMode) { + console.warn(disabledAttrWarning); + } + } + // TODO(kara): remove next 4 properties once deprecation period is over + /** @deprecated as of v6 */ + model; + /** @deprecated as of v6 */ + update = new EventEmitter(); + /** + * @description + * Static property used to track whether any ngModel warnings have been sent across + * all instances of FormControlName. Used to support warning config of "once". + * + * @internal + */ + static _ngModelWarningSentOnce = false; + /** + * @description + * Instance property used to track whether an ngModel warning has been sent out for this + * particular FormControlName instance. Used to support warning config of "always". + * + * @internal + */ + _ngModelWarningSent = false; + constructor(parent, validators, asyncValidators, valueAccessors, _ngModelWarningConfig) { + super(); + this._ngModelWarningConfig = _ngModelWarningConfig; + this._parent = parent; + this._setValidators(validators); + this._setAsyncValidators(asyncValidators); + this.valueAccessor = selectValueAccessor(this, valueAccessors); + } + /** @docs-private */ + ngOnChanges(changes) { + if (!this._added) this._setUpControl(); + if (isPropertyUpdated(changes, this.viewModel)) { + if (typeof ngDevMode === "undefined" || ngDevMode) { + _ngModelWarning("formControlName", _FormControlName, this, this._ngModelWarningConfig); + } + this.viewModel = this.model; + this.formDirective.updateModel(this, this.model); + } + } + /** @docs-private */ + ngOnDestroy() { + if (this.formDirective) { + this.formDirective.removeControl(this); + } + } + /** + * @description + * Sets the new value for the view model and emits an `ngModelChange` event. + * + * @param newValue The new value for the view model. + */ + viewToModelUpdate(newValue) { + this.viewModel = newValue; + this.update.emit(newValue); + } + /** + * @description + * Returns an array that represents the path from the top-level form to this control. + * Each index is the string name of the control on that level. + */ + get path() { + return controlPath(this.name == null ? this.name : this.name.toString(), this._parent); + } + /** + * @description + * The top-level directive for this group if present, otherwise null. + */ + get formDirective() { + return this._parent ? this._parent.formDirective : null; + } + _setUpControl() { + if (typeof ngDevMode === "undefined" || ngDevMode) { + checkParentType(this._parent, this.name); + } + this.control = this.formDirective.addControl(this); + this._added = true; + } + static ɵfac = function FormControlName_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _FormControlName)(ɵɵdirectiveInject(ControlContainer, 13), ɵɵdirectiveInject(NG_VALIDATORS, 10), ɵɵdirectiveInject(NG_ASYNC_VALIDATORS, 10), ɵɵdirectiveInject(NG_VALUE_ACCESSOR, 10), ɵɵdirectiveInject(NG_MODEL_WITH_FORM_CONTROL_WARNING, 8)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _FormControlName, + selectors: [["", "formControlName", ""]], + inputs: { + name: [0, "formControlName", "name"], + isDisabled: [0, "disabled", "isDisabled"], + model: [0, "ngModel", "model"] + }, + outputs: { + update: "ngModelChange" + }, + standalone: false, + features: [ɵɵProvidersFeature([controlNameBinding]), ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(FormControlName, [{ + type: Directive, + args: [{ + selector: "[formControlName]", + providers: [controlNameBinding], + standalone: false + }] + }], () => [{ + type: ControlContainer, + decorators: [{ + type: Optional + }, { + type: Host + }, { + type: SkipSelf + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_ASYNC_VALIDATORS] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Self + }, { + type: Inject, + args: [NG_VALUE_ACCESSOR] + }] + }, { + type: void 0, + decorators: [{ + type: Optional + }, { + type: Inject, + args: [NG_MODEL_WITH_FORM_CONTROL_WARNING] + }] + }], { + name: [{ + type: Input, + args: ["formControlName"] + }], + isDisabled: [{ + type: Input, + args: ["disabled"] + }], + model: [{ + type: Input, + args: ["ngModel"] + }], + update: [{ + type: Output, + args: ["ngModelChange"] + }] + }); +})(); +function checkParentType(parent, name) { + if (!(parent instanceof FormGroupName) && parent instanceof AbstractFormGroupDirective) { + throw ngModelGroupException(); + } else if (!(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) && !(parent instanceof FormArrayName)) { + throw controlParentException(name); + } +} +var SELECT_VALUE_ACCESSOR = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => SelectControlValueAccessor), + multi: true +}; +function _buildValueString$1(id, value) { + if (id == null) return `${value}`; + if (value && typeof value === "object") value = "Object"; + return `${id}: ${value}`.slice(0, 50); +} +function _extractId$1(valueString) { + return valueString.split(":")[0]; +} +var SelectControlValueAccessor = class _SelectControlValueAccessor extends BuiltInControlValueAccessor { + /** @docs-private */ + value; + /** @internal */ + _optionMap = /* @__PURE__ */ new Map(); + /** @internal */ + _idCounter = 0; + /** + * @description + * Tracks the option comparison algorithm for tracking identities when + * checking for changes. + */ + set compareWith(fn) { + if (typeof fn !== "function" && (typeof ngDevMode === "undefined" || ngDevMode)) { + throw new RuntimeError(1201, `compareWith must be a function, but received ${JSON.stringify(fn)}`); + } + this._compareWith = fn; + } + _compareWith = Object.is; + // We need this because we might be in the process of destroying the root + // injector, which is marked as destroyed before running destroy hooks. + // Attempting to use afterNextRender with the node injector would evntually + // run into that already destroyed injector. + appRefInjector = inject(ApplicationRef).injector; + destroyRef = inject(DestroyRef); + cdr = inject(ChangeDetectorRef); + _queuedWrite = false; + /** + * This is needed to efficiently set the select value when adding/removing options. If + * writeValue is instead called for every added/removed option, this results in exponentially + * more _compareValue calls than the number of option elements (issue #41330). + * + * Secondly, calling writeValue when rendering individual option elements instead of after they + * are all rendered caused an issue in Safari and IE 11 where the first option element failed + * to be deselected when no option matched the select ngModel. This was because Angular would + * set the select element's value property before appending the option's child text node to the + * DOM (issue #14505). + * + * Finally, this approach is necessary to avoid an issue with delayed element removal when + * using the animations module (in all browsers). Otherwise when a selected option is removed + * (so no option matches the ngModel anymore), Angular would change the select element value + * before actually removing the option from the DOM. Then when the option is finally removed + * from the DOM, the browser would change the select value to that of the first option, even + * though it doesn't match the ngModel (issue #18430). + * + * @internal + */ + _writeValueAfterRender() { + if (this._queuedWrite || this.appRefInjector.destroyed) { + return; + } + this._queuedWrite = true; + afterNextRender({ + write: () => { + if (this.destroyRef.destroyed) { + return; + } + this._queuedWrite = false; + this.writeValue(this.value); + } + }, { + injector: this.appRefInjector + }); + } + /** + * Sets the "value" property on the select element. + * @docs-private + */ + writeValue(value) { + this.cdr.markForCheck(); + this.value = value; + const id = this._getOptionId(value); + const valueString = _buildValueString$1(id, value); + this.setProperty("value", valueString); + } + /** + * Registers a function called when the control value changes. + * @docs-private + */ + registerOnChange(fn) { + this.onChange = (valueString) => { + this.value = this._getOptionValue(valueString); + fn(this.value); + }; + } + /** @internal */ + _registerOption() { + return (this._idCounter++).toString(); + } + /** @internal */ + _getOptionId(value) { + for (const id of this._optionMap.keys()) { + if (this._compareWith(this._optionMap.get(id), value)) return id; + } + return null; + } + /** @internal */ + _getOptionValue(valueString) { + const id = _extractId$1(valueString); + return this._optionMap.has(id) ? this._optionMap.get(id) : valueString; + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵSelectControlValueAccessor_BaseFactory; + return function SelectControlValueAccessor_Factory(__ngFactoryType__) { + return (ɵSelectControlValueAccessor_BaseFactory || (ɵSelectControlValueAccessor_BaseFactory = ɵɵgetInheritedFactory(_SelectControlValueAccessor)))(__ngFactoryType__ || _SelectControlValueAccessor); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _SelectControlValueAccessor, + selectors: [["select", "formControlName", "", 3, "multiple", ""], ["select", "formControl", "", 3, "multiple", ""], ["select", "ngModel", "", 3, "multiple", ""]], + hostBindings: function SelectControlValueAccessor_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("change", function SelectControlValueAccessor_change_HostBindingHandler($event) { + return ctx.onChange($event.target.value); + })("blur", function SelectControlValueAccessor_blur_HostBindingHandler() { + return ctx.onTouched(); + }); + } + }, + inputs: { + compareWith: "compareWith" + }, + standalone: false, + features: [ɵɵProvidersFeature([SELECT_VALUE_ACCESSOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(SelectControlValueAccessor, [{ + type: Directive, + args: [{ + selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", + host: { + "(change)": "onChange($any($event.target).value)", + "(blur)": "onTouched()" + }, + providers: [SELECT_VALUE_ACCESSOR], + standalone: false + }] + }], null, { + compareWith: [{ + type: Input + }] + }); +})(); +var NgSelectOption = class _NgSelectOption { + _element; + _renderer; + _select; + /** + * @description + * ID of the option element + */ + id; + constructor(_element, _renderer, _select) { + this._element = _element; + this._renderer = _renderer; + this._select = _select; + if (this._select) this.id = this._select._registerOption(); + } + /** + * @description + * Tracks the value bound to the option element. Unlike the value binding, + * ngValue supports binding to objects. + */ + set ngValue(value) { + if (this._select == null) return; + this._select._optionMap.set(this.id, value); + this._setElementValue(_buildValueString$1(this.id, value)); + this._select._writeValueAfterRender(); + } + /** + * @description + * Tracks simple string values bound to the option element. + * For objects, use the `ngValue` input binding. + */ + set value(value) { + this._setElementValue(value); + if (this._select) this._select._writeValueAfterRender(); + } + /** @internal */ + _setElementValue(value) { + this._renderer.setProperty(this._element.nativeElement, "value", value); + } + /** @docs-private */ + ngOnDestroy() { + if (this._select) { + this._select._optionMap.delete(this.id); + this._select._writeValueAfterRender(); + } + } + static ɵfac = function NgSelectOption_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _NgSelectOption)(ɵɵdirectiveInject(ElementRef), ɵɵdirectiveInject(Renderer2), ɵɵdirectiveInject(SelectControlValueAccessor, 9)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _NgSelectOption, + selectors: [["option"]], + inputs: { + ngValue: "ngValue", + value: "value" + }, + standalone: false + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgSelectOption, [{ + type: Directive, + args: [{ + selector: "option", + standalone: false + }] + }], () => [{ + type: ElementRef + }, { + type: Renderer2 + }, { + type: SelectControlValueAccessor, + decorators: [{ + type: Optional + }, { + type: Host + }] + }], { + ngValue: [{ + type: Input, + args: ["ngValue"] + }], + value: [{ + type: Input, + args: ["value"] + }] + }); +})(); +var SELECT_MULTIPLE_VALUE_ACCESSOR = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => SelectMultipleControlValueAccessor), + multi: true +}; +function _buildValueString(id, value) { + if (id == null) return `${value}`; + if (typeof value === "string") value = `'${value}'`; + if (value && typeof value === "object") value = "Object"; + return `${id}: ${value}`.slice(0, 50); +} +function _extractId(valueString) { + return valueString.split(":")[0]; +} +var SelectMultipleControlValueAccessor = class _SelectMultipleControlValueAccessor extends BuiltInControlValueAccessor { + /** + * The current value. + * @docs-private + */ + value; + /** @internal */ + _optionMap = /* @__PURE__ */ new Map(); + /** @internal */ + _idCounter = 0; + /** + * @description + * Tracks the option comparison algorithm for tracking identities when + * checking for changes. + */ + set compareWith(fn) { + if (typeof fn !== "function" && (typeof ngDevMode === "undefined" || ngDevMode)) { + throw new RuntimeError(1201, `compareWith must be a function, but received ${JSON.stringify(fn)}`); + } + this._compareWith = fn; + } + _compareWith = Object.is; + /** + * Sets the "value" property on one or of more of the select's options. + * @docs-private + */ + writeValue(value) { + this.value = value; + let optionSelectedStateSetter; + if (Array.isArray(value)) { + const ids = value.map((v) => this._getOptionId(v)); + optionSelectedStateSetter = (opt, o) => { + opt._setSelected(ids.indexOf(o.toString()) > -1); + }; + } else { + optionSelectedStateSetter = (opt, o) => { + opt._setSelected(false); + }; + } + this._optionMap.forEach(optionSelectedStateSetter); + } + /** + * Registers a function called when the control value changes + * and writes an array of the selected options. + * @docs-private + */ + registerOnChange(fn) { + this.onChange = (element) => { + const selected = []; + const selectedOptions = element.selectedOptions; + if (selectedOptions !== void 0) { + const options = selectedOptions; + for (let i = 0; i < options.length; i++) { + const opt = options[i]; + const val = this._getOptionValue(opt.value); + selected.push(val); + } + } else { + const options = element.options; + for (let i = 0; i < options.length; i++) { + const opt = options[i]; + if (opt.selected) { + const val = this._getOptionValue(opt.value); + selected.push(val); + } + } + } + this.value = selected; + fn(selected); + }; + } + /** @internal */ + _registerOption(value) { + const id = (this._idCounter++).toString(); + this._optionMap.set(id, value); + return id; + } + /** @internal */ + _getOptionId(value) { + for (const id of this._optionMap.keys()) { + if (this._compareWith(this._optionMap.get(id)._value, value)) return id; + } + return null; + } + /** @internal */ + _getOptionValue(valueString) { + const id = _extractId(valueString); + return this._optionMap.has(id) ? this._optionMap.get(id)._value : valueString; + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵSelectMultipleControlValueAccessor_BaseFactory; + return function SelectMultipleControlValueAccessor_Factory(__ngFactoryType__) { + return (ɵSelectMultipleControlValueAccessor_BaseFactory || (ɵSelectMultipleControlValueAccessor_BaseFactory = ɵɵgetInheritedFactory(_SelectMultipleControlValueAccessor)))(__ngFactoryType__ || _SelectMultipleControlValueAccessor); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _SelectMultipleControlValueAccessor, + selectors: [["select", "multiple", "", "formControlName", ""], ["select", "multiple", "", "formControl", ""], ["select", "multiple", "", "ngModel", ""]], + hostBindings: function SelectMultipleControlValueAccessor_HostBindings(rf, ctx) { + if (rf & 1) { + ɵɵlistener("change", function SelectMultipleControlValueAccessor_change_HostBindingHandler($event) { + return ctx.onChange($event.target); + })("blur", function SelectMultipleControlValueAccessor_blur_HostBindingHandler() { + return ctx.onTouched(); + }); + } + }, + inputs: { + compareWith: "compareWith" + }, + standalone: false, + features: [ɵɵProvidersFeature([SELECT_MULTIPLE_VALUE_ACCESSOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(SelectMultipleControlValueAccessor, [{ + type: Directive, + args: [{ + selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", + host: { + "(change)": "onChange($event.target)", + "(blur)": "onTouched()" + }, + providers: [SELECT_MULTIPLE_VALUE_ACCESSOR], + standalone: false + }] + }], null, { + compareWith: [{ + type: Input + }] + }); +})(); +var ɵNgSelectMultipleOption = class _ɵNgSelectMultipleOption { + _element; + _renderer; + _select; + id; + /** @internal */ + _value; + constructor(_element, _renderer, _select) { + this._element = _element; + this._renderer = _renderer; + this._select = _select; + if (this._select) { + this.id = this._select._registerOption(this); + } + } + /** + * @description + * Tracks the value bound to the option element. Unlike the value binding, + * ngValue supports binding to objects. + */ + set ngValue(value) { + if (this._select == null) return; + this._value = value; + this._setElementValue(_buildValueString(this.id, value)); + this._select.writeValue(this._select.value); + } + /** + * @description + * Tracks simple string values bound to the option element. + * For objects, use the `ngValue` input binding. + */ + set value(value) { + if (this._select) { + this._value = value; + this._setElementValue(_buildValueString(this.id, value)); + this._select.writeValue(this._select.value); + } else { + this._setElementValue(value); + } + } + /** @internal */ + _setElementValue(value) { + this._renderer.setProperty(this._element.nativeElement, "value", value); + } + /** @internal */ + _setSelected(selected) { + this._renderer.setProperty(this._element.nativeElement, "selected", selected); + } + /** @docs-private */ + ngOnDestroy() { + if (this._select) { + this._select._optionMap.delete(this.id); + this._select.writeValue(this._select.value); + } + } + static ɵfac = function ɵNgSelectMultipleOption_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _ɵNgSelectMultipleOption)(ɵɵdirectiveInject(ElementRef), ɵɵdirectiveInject(Renderer2), ɵɵdirectiveInject(SelectMultipleControlValueAccessor, 9)); + }; + static ɵdir = ɵɵdefineDirective({ + type: _ɵNgSelectMultipleOption, + selectors: [["option"]], + inputs: { + ngValue: "ngValue", + value: "value" + }, + standalone: false + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ɵNgSelectMultipleOption, [{ + type: Directive, + args: [{ + selector: "option", + standalone: false + }] + }], () => [{ + type: ElementRef + }, { + type: Renderer2 + }, { + type: SelectMultipleControlValueAccessor, + decorators: [{ + type: Optional + }, { + type: Host + }] + }], { + ngValue: [{ + type: Input, + args: ["ngValue"] + }], + value: [{ + type: Input, + args: ["value"] + }] + }); +})(); +function toInteger(value) { + return typeof value === "number" ? value : parseInt(value, 10); +} +function toFloat(value) { + return typeof value === "number" ? value : parseFloat(value); +} +var AbstractValidatorDirective = class _AbstractValidatorDirective { + _validator = nullValidator; + _onChange; + /** + * A flag that tracks whether this validator is enabled. + * + * Marking it `internal` (vs `protected`), so that this flag can be used in host bindings of + * directive classes that extend this base class. + * @internal + */ + _enabled; + /** @docs-private */ + ngOnChanges(changes) { + if (this.inputName in changes) { + const input = this.normalizeInput(changes[this.inputName].currentValue); + this._enabled = this.enabled(input); + this._validator = this._enabled ? this.createValidator(input) : nullValidator; + if (this._onChange) { + this._onChange(); + } + } + } + /** @docs-private */ + validate(control) { + return this._validator(control); + } + /** @docs-private */ + registerOnValidatorChange(fn) { + this._onChange = fn; + } + /** + * @description + * Determines whether this validator should be active or not based on an input. + * Base class implementation checks whether an input is defined (if the value is different from + * `null` and `undefined`). Validator classes that extend this base class can override this + * function with the logic specific to a particular validator directive. + */ + enabled(input) { + return input != null; + } + static ɵfac = function AbstractValidatorDirective_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _AbstractValidatorDirective)(); + }; + static ɵdir = ɵɵdefineDirective({ + type: _AbstractValidatorDirective, + features: [ɵɵNgOnChangesFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(AbstractValidatorDirective, [{ + type: Directive + }], null, null); +})(); +var MAX_VALIDATOR = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => MaxValidator), + multi: true +}; +var MaxValidator = class _MaxValidator extends AbstractValidatorDirective { + /** + * @description + * Tracks changes to the max bound to this directive. + */ + max; + /** @internal */ + inputName = "max"; + /** @internal */ + normalizeInput = (input) => toFloat(input); + /** @internal */ + createValidator = (max) => maxValidator(max); + static ɵfac = /* @__PURE__ */ (() => { + let ɵMaxValidator_BaseFactory; + return function MaxValidator_Factory(__ngFactoryType__) { + return (ɵMaxValidator_BaseFactory || (ɵMaxValidator_BaseFactory = ɵɵgetInheritedFactory(_MaxValidator)))(__ngFactoryType__ || _MaxValidator); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _MaxValidator, + selectors: [["input", "type", "number", "max", "", "formControlName", ""], ["input", "type", "number", "max", "", "formControl", ""], ["input", "type", "number", "max", "", "ngModel", ""]], + hostVars: 1, + hostBindings: function MaxValidator_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵattribute("max", ctx._enabled ? ctx.max : null); + } + }, + inputs: { + max: "max" + }, + standalone: false, + features: [ɵɵProvidersFeature([MAX_VALIDATOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(MaxValidator, [{ + type: Directive, + args: [{ + selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", + providers: [MAX_VALIDATOR], + host: { + "[attr.max]": "_enabled ? max : null" + }, + standalone: false + }] + }], null, { + max: [{ + type: Input + }] + }); +})(); +var MIN_VALIDATOR = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => MinValidator), + multi: true +}; +var MinValidator = class _MinValidator extends AbstractValidatorDirective { + /** + * @description + * Tracks changes to the min bound to this directive. + */ + min; + /** @internal */ + inputName = "min"; + /** @internal */ + normalizeInput = (input) => toFloat(input); + /** @internal */ + createValidator = (min) => minValidator(min); + static ɵfac = /* @__PURE__ */ (() => { + let ɵMinValidator_BaseFactory; + return function MinValidator_Factory(__ngFactoryType__) { + return (ɵMinValidator_BaseFactory || (ɵMinValidator_BaseFactory = ɵɵgetInheritedFactory(_MinValidator)))(__ngFactoryType__ || _MinValidator); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _MinValidator, + selectors: [["input", "type", "number", "min", "", "formControlName", ""], ["input", "type", "number", "min", "", "formControl", ""], ["input", "type", "number", "min", "", "ngModel", ""]], + hostVars: 1, + hostBindings: function MinValidator_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵattribute("min", ctx._enabled ? ctx.min : null); + } + }, + inputs: { + min: "min" + }, + standalone: false, + features: [ɵɵProvidersFeature([MIN_VALIDATOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(MinValidator, [{ + type: Directive, + args: [{ + selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", + providers: [MIN_VALIDATOR], + host: { + "[attr.min]": "_enabled ? min : null" + }, + standalone: false + }] + }], null, { + min: [{ + type: Input + }] + }); +})(); +var REQUIRED_VALIDATOR = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => RequiredValidator), + multi: true +}; +var CHECKBOX_REQUIRED_VALIDATOR = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => CheckboxRequiredValidator), + multi: true +}; +var RequiredValidator = class _RequiredValidator extends AbstractValidatorDirective { + /** + * @description + * Tracks changes to the required attribute bound to this directive. + */ + required; + /** @internal */ + inputName = "required"; + /** @internal */ + normalizeInput = booleanAttribute; + /** @internal */ + createValidator = (input) => requiredValidator; + /** @docs-private */ + enabled(input) { + return input; + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵRequiredValidator_BaseFactory; + return function RequiredValidator_Factory(__ngFactoryType__) { + return (ɵRequiredValidator_BaseFactory || (ɵRequiredValidator_BaseFactory = ɵɵgetInheritedFactory(_RequiredValidator)))(__ngFactoryType__ || _RequiredValidator); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _RequiredValidator, + selectors: [["", "required", "", "formControlName", "", 3, "type", "checkbox"], ["", "required", "", "formControl", "", 3, "type", "checkbox"], ["", "required", "", "ngModel", "", 3, "type", "checkbox"]], + hostVars: 1, + hostBindings: function RequiredValidator_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵattribute("required", ctx._enabled ? "" : null); + } + }, + inputs: { + required: "required" + }, + standalone: false, + features: [ɵɵProvidersFeature([REQUIRED_VALIDATOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RequiredValidator, [{ + type: Directive, + args: [{ + selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", + providers: [REQUIRED_VALIDATOR], + host: { + "[attr.required]": '_enabled ? "" : null' + }, + standalone: false + }] + }], null, { + required: [{ + type: Input + }] + }); +})(); +var CheckboxRequiredValidator = class _CheckboxRequiredValidator extends RequiredValidator { + /** @internal */ + createValidator = (input) => requiredTrueValidator; + static ɵfac = /* @__PURE__ */ (() => { + let ɵCheckboxRequiredValidator_BaseFactory; + return function CheckboxRequiredValidator_Factory(__ngFactoryType__) { + return (ɵCheckboxRequiredValidator_BaseFactory || (ɵCheckboxRequiredValidator_BaseFactory = ɵɵgetInheritedFactory(_CheckboxRequiredValidator)))(__ngFactoryType__ || _CheckboxRequiredValidator); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _CheckboxRequiredValidator, + selectors: [["input", "type", "checkbox", "required", "", "formControlName", ""], ["input", "type", "checkbox", "required", "", "formControl", ""], ["input", "type", "checkbox", "required", "", "ngModel", ""]], + hostVars: 1, + hostBindings: function CheckboxRequiredValidator_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵattribute("required", ctx._enabled ? "" : null); + } + }, + standalone: false, + features: [ɵɵProvidersFeature([CHECKBOX_REQUIRED_VALIDATOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(CheckboxRequiredValidator, [{ + type: Directive, + args: [{ + selector: "input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]", + providers: [CHECKBOX_REQUIRED_VALIDATOR], + host: { + "[attr.required]": '_enabled ? "" : null' + }, + standalone: false + }] + }], null, null); +})(); +var EMAIL_VALIDATOR = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => EmailValidator), + multi: true +}; +var EmailValidator = class _EmailValidator extends AbstractValidatorDirective { + /** + * @description + * Tracks changes to the email attribute bound to this directive. + */ + email; + /** @internal */ + inputName = "email"; + /** @internal */ + normalizeInput = booleanAttribute; + /** @internal */ + createValidator = (input) => emailValidator; + /** @docs-private */ + enabled(input) { + return input; + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵEmailValidator_BaseFactory; + return function EmailValidator_Factory(__ngFactoryType__) { + return (ɵEmailValidator_BaseFactory || (ɵEmailValidator_BaseFactory = ɵɵgetInheritedFactory(_EmailValidator)))(__ngFactoryType__ || _EmailValidator); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _EmailValidator, + selectors: [["", "email", "", "formControlName", ""], ["", "email", "", "formControl", ""], ["", "email", "", "ngModel", ""]], + inputs: { + email: "email" + }, + standalone: false, + features: [ɵɵProvidersFeature([EMAIL_VALIDATOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(EmailValidator, [{ + type: Directive, + args: [{ + selector: "[email][formControlName],[email][formControl],[email][ngModel]", + providers: [EMAIL_VALIDATOR], + standalone: false + }] + }], null, { + email: [{ + type: Input + }] + }); +})(); +var MIN_LENGTH_VALIDATOR = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => MinLengthValidator), + multi: true +}; +var MinLengthValidator = class _MinLengthValidator extends AbstractValidatorDirective { + /** + * @description + * Tracks changes to the minimum length bound to this directive. + */ + minlength; + /** @internal */ + inputName = "minlength"; + /** @internal */ + normalizeInput = (input) => toInteger(input); + /** @internal */ + createValidator = (minlength) => minLengthValidator(minlength); + static ɵfac = /* @__PURE__ */ (() => { + let ɵMinLengthValidator_BaseFactory; + return function MinLengthValidator_Factory(__ngFactoryType__) { + return (ɵMinLengthValidator_BaseFactory || (ɵMinLengthValidator_BaseFactory = ɵɵgetInheritedFactory(_MinLengthValidator)))(__ngFactoryType__ || _MinLengthValidator); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _MinLengthValidator, + selectors: [["", "minlength", "", "formControlName", ""], ["", "minlength", "", "formControl", ""], ["", "minlength", "", "ngModel", ""]], + hostVars: 1, + hostBindings: function MinLengthValidator_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵattribute("minlength", ctx._enabled ? ctx.minlength : null); + } + }, + inputs: { + minlength: "minlength" + }, + standalone: false, + features: [ɵɵProvidersFeature([MIN_LENGTH_VALIDATOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(MinLengthValidator, [{ + type: Directive, + args: [{ + selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", + providers: [MIN_LENGTH_VALIDATOR], + host: { + "[attr.minlength]": "_enabled ? minlength : null" + }, + standalone: false + }] + }], null, { + minlength: [{ + type: Input + }] + }); +})(); +var MAX_LENGTH_VALIDATOR = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => MaxLengthValidator), + multi: true +}; +var MaxLengthValidator = class _MaxLengthValidator extends AbstractValidatorDirective { + /** + * @description + * Tracks changes to the maximum length bound to this directive. + */ + maxlength; + /** @internal */ + inputName = "maxlength"; + /** @internal */ + normalizeInput = (input) => toInteger(input); + /** @internal */ + createValidator = (maxlength) => maxLengthValidator(maxlength); + static ɵfac = /* @__PURE__ */ (() => { + let ɵMaxLengthValidator_BaseFactory; + return function MaxLengthValidator_Factory(__ngFactoryType__) { + return (ɵMaxLengthValidator_BaseFactory || (ɵMaxLengthValidator_BaseFactory = ɵɵgetInheritedFactory(_MaxLengthValidator)))(__ngFactoryType__ || _MaxLengthValidator); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _MaxLengthValidator, + selectors: [["", "maxlength", "", "formControlName", ""], ["", "maxlength", "", "formControl", ""], ["", "maxlength", "", "ngModel", ""]], + hostVars: 1, + hostBindings: function MaxLengthValidator_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵattribute("maxlength", ctx._enabled ? ctx.maxlength : null); + } + }, + inputs: { + maxlength: "maxlength" + }, + standalone: false, + features: [ɵɵProvidersFeature([MAX_LENGTH_VALIDATOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(MaxLengthValidator, [{ + type: Directive, + args: [{ + selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", + providers: [MAX_LENGTH_VALIDATOR], + host: { + "[attr.maxlength]": "_enabled ? maxlength : null" + }, + standalone: false + }] + }], null, { + maxlength: [{ + type: Input + }] + }); +})(); +var PATTERN_VALIDATOR = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => PatternValidator), + multi: true +}; +var PatternValidator = class _PatternValidator extends AbstractValidatorDirective { + /** + * @description + * Tracks changes to the pattern bound to this directive. + */ + pattern; + // This input is always defined, since the name matches selector. + /** @internal */ + inputName = "pattern"; + /** @internal */ + normalizeInput = (input) => input; + /** @internal */ + createValidator = (input) => patternValidator(input); + static ɵfac = /* @__PURE__ */ (() => { + let ɵPatternValidator_BaseFactory; + return function PatternValidator_Factory(__ngFactoryType__) { + return (ɵPatternValidator_BaseFactory || (ɵPatternValidator_BaseFactory = ɵɵgetInheritedFactory(_PatternValidator)))(__ngFactoryType__ || _PatternValidator); + }; + })(); + static ɵdir = ɵɵdefineDirective({ + type: _PatternValidator, + selectors: [["", "pattern", "", "formControlName", ""], ["", "pattern", "", "formControl", ""], ["", "pattern", "", "ngModel", ""]], + hostVars: 1, + hostBindings: function PatternValidator_HostBindings(rf, ctx) { + if (rf & 2) { + ɵɵattribute("pattern", ctx._enabled ? ctx.pattern : null); + } + }, + inputs: { + pattern: "pattern" + }, + standalone: false, + features: [ɵɵProvidersFeature([PATTERN_VALIDATOR]), ɵɵInheritDefinitionFeature] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PatternValidator, [{ + type: Directive, + args: [{ + selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", + providers: [PATTERN_VALIDATOR], + host: { + "[attr.pattern]": "_enabled ? pattern : null" + }, + standalone: false + }] + }], null, { + pattern: [{ + type: Input + }] + }); +})(); +var SHARED_FORM_DIRECTIVES = [ɵNgNoValidate, NgSelectOption, ɵNgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, RangeValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, RadioControlValueAccessor, NgControlStatus, NgControlStatusGroup, RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, CheckboxRequiredValidator, EmailValidator, MinValidator, MaxValidator]; +var TEMPLATE_DRIVEN_DIRECTIVES = [NgModel, NgModelGroup, NgForm]; +var REACTIVE_DRIVEN_DIRECTIVES = [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName]; +var ɵInternalFormsSharedModule = class _ɵInternalFormsSharedModule { + static ɵfac = function ɵInternalFormsSharedModule_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _ɵInternalFormsSharedModule)(); + }; + static ɵmod = ɵɵdefineNgModule({ + type: _ɵInternalFormsSharedModule, + declarations: [ɵNgNoValidate, NgSelectOption, ɵNgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, RangeValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, RadioControlValueAccessor, NgControlStatus, NgControlStatusGroup, RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, CheckboxRequiredValidator, EmailValidator, MinValidator, MaxValidator], + exports: [ɵNgNoValidate, NgSelectOption, ɵNgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, RangeValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, RadioControlValueAccessor, NgControlStatus, NgControlStatusGroup, RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, CheckboxRequiredValidator, EmailValidator, MinValidator, MaxValidator] + }); + static ɵinj = ɵɵdefineInjector({}); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ɵInternalFormsSharedModule, [{ + type: NgModule, + args: [{ + declarations: SHARED_FORM_DIRECTIVES, + exports: SHARED_FORM_DIRECTIVES + }] + }], null, null); +})(); +var FormArray = class extends AbstractControl { + /** + * Creates a new `FormArray` instance. + * + * @param controls An array of child controls. Each child control is given an index + * where it is registered. + * + * @param validatorOrOpts A synchronous validator function, or an array of + * such functions, or an `AbstractControlOptions` object that contains validation functions + * and a validation trigger. + * + * @param asyncValidator A single async validator or array of async validator functions + * + */ + constructor(controls, validatorOrOpts, asyncValidator) { + super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts)); + this.controls = controls; + this._initObservables(); + this._setUpdateStrategy(validatorOrOpts); + this._setUpControls(); + this.updateValueAndValidity({ + onlySelf: true, + // If `asyncValidator` is present, it will trigger control status change from `PENDING` to + // `VALID` or `INVALID`. + // The status should be broadcasted via the `statusChanges` observable, so we set `emitEvent` + // to `true` to allow that during the control creation process. + emitEvent: !!this.asyncValidator + }); + } + controls; + /** + * Get the `AbstractControl` at the given `index` in the array. + * + * @param index Index in the array to retrieve the control. If `index` is negative, it will wrap + * around from the back, and if index is greatly negative (less than `-length`), the result is + * undefined. This behavior is the same as `Array.at(index)`. + */ + at(index) { + return this.controls[this._adjustIndex(index)]; + } + /** + * Insert a new `AbstractControl` at the end of the array. + * + * @param control Form control to be inserted + * @param options Specifies whether this FormArray instance should emit events after a new + * control is added. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` observables emit events with the latest status and value when the control is + * inserted. When false, no events are emitted. + */ + push(control, options = {}) { + if (Array.isArray(control)) { + control.forEach((ctrl) => { + this.controls.push(ctrl); + this._registerControl(ctrl); + }); + } else { + this.controls.push(control); + this._registerControl(control); + } + this.updateValueAndValidity({ + emitEvent: options.emitEvent + }); + this._onCollectionChange(); + } + /** + * Insert a new `AbstractControl` at the given `index` in the array. + * + * @param index Index in the array to insert the control. If `index` is negative, wraps around + * from the back. If `index` is greatly negative (less than `-length`), prepends to the array. + * This behavior is the same as `Array.splice(index, 0, control)`. + * @param control Form control to be inserted + * @param options Specifies whether this FormArray instance should emit events after a new + * control is inserted. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` observables emit events with the latest status and value when the control is + * inserted. When false, no events are emitted. + */ + insert(index, control, options = {}) { + this.controls.splice(index, 0, control); + this._registerControl(control); + this.updateValueAndValidity({ + emitEvent: options.emitEvent + }); + } + /** + * Remove the control at the given `index` in the array. + * + * @param index Index in the array to remove the control. If `index` is negative, wraps around + * from the back. If `index` is greatly negative (less than `-length`), removes the first + * element. This behavior is the same as `Array.splice(index, 1)`. + * @param options Specifies whether this FormArray instance should emit events after a + * control is removed. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` observables emit events with the latest status and value when the control is + * removed. When false, no events are emitted. + */ + removeAt(index, options = {}) { + let adjustedIndex = this._adjustIndex(index); + if (adjustedIndex < 0) adjustedIndex = 0; + if (this.controls[adjustedIndex]) this.controls[adjustedIndex]._registerOnCollectionChange(() => { + }); + this.controls.splice(adjustedIndex, 1); + this.updateValueAndValidity({ + emitEvent: options.emitEvent + }); + } + /** + * Replace an existing control. + * + * @param index Index in the array to replace the control. If `index` is negative, wraps around + * from the back. If `index` is greatly negative (less than `-length`), replaces the first + * element. This behavior is the same as `Array.splice(index, 1, control)`. + * @param control The `AbstractControl` control to replace the existing control + * @param options Specifies whether this FormArray instance should emit events after an + * existing control is replaced with a new one. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` observables emit events with the latest status and value when the control is + * replaced with a new one. When false, no events are emitted. + */ + setControl(index, control, options = {}) { + let adjustedIndex = this._adjustIndex(index); + if (adjustedIndex < 0) adjustedIndex = 0; + if (this.controls[adjustedIndex]) this.controls[adjustedIndex]._registerOnCollectionChange(() => { + }); + this.controls.splice(adjustedIndex, 1); + if (control) { + this.controls.splice(adjustedIndex, 0, control); + this._registerControl(control); + } + this.updateValueAndValidity({ + emitEvent: options.emitEvent + }); + this._onCollectionChange(); + } + /** + * Length of the control array. + */ + get length() { + return this.controls.length; + } + /** + * Sets the value of the `FormArray`. It accepts an array that matches + * the structure of the control. + * + * This method performs strict checks, and throws an error if you try + * to set the value of a control that doesn't exist or if you exclude the + * value of a control. + * + * @usageNotes + * ### Set the values for the controls in the form array + * + * ```ts + * const arr = new FormArray([ + * new FormControl(), + * new FormControl() + * ]); + * console.log(arr.value); // [null, null] + * + * arr.setValue(['Nancy', 'Drew']); + * console.log(arr.value); // ['Nancy', 'Drew'] + * ``` + * + * @param value Array of values for the controls + * @param options Configure options that determine how the control propagates changes and + * emits events after the value changes + * + * * `onlySelf`: When true, each change only affects this control, and not its parent. Default + * is false. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` + * observables emit events with the latest status and value when the control value is updated. + * When false, no events are emitted. + * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity + * updateValueAndValidity} method. + */ + setValue(value, options = {}) { + assertAllValuesPresent(this, false, value); + value.forEach((newValue, index) => { + assertControlPresent(this, false, index); + this.at(index).setValue(newValue, { + onlySelf: true, + emitEvent: options.emitEvent + }); + }); + this.updateValueAndValidity(options); + } + /** + * Patches the value of the `FormArray`. It accepts an array that matches the + * structure of the control, and does its best to match the values to the correct + * controls in the group. + * + * It accepts both super-sets and sub-sets of the array without throwing an error. + * + * @usageNotes + * ### Patch the values for controls in a form array + * + * ```ts + * const arr = new FormArray([ + * new FormControl(), + * new FormControl() + * ]); + * console.log(arr.value); // [null, null] + * + * arr.patchValue(['Nancy']); + * console.log(arr.value); // ['Nancy', null] + * ``` + * + * @param value Array of latest values for the controls + * @param options Configure options that determine how the control propagates changes and + * emits events after the value changes + * + * * `onlySelf`: When true, each change only affects this control, and not its parent. Default + * is false. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` observables emit events with the latest status and value when the control + * value is updated. When false, no events are emitted. The configuration options are passed to + * the {@link AbstractControl#updateValueAndValidity updateValueAndValidity} method. + */ + patchValue(value, options = {}) { + if (value == null) return; + value.forEach((newValue, index) => { + if (this.at(index)) { + this.at(index).patchValue(newValue, { + onlySelf: true, + emitEvent: options.emitEvent + }); + } + }); + this.updateValueAndValidity(options); + } + /** + * Resets the `FormArray` and all descendants are marked `pristine` and `untouched`, and the + * value of all descendants to null or null maps. + * + * You reset to a specific form state by passing in an array of states + * that matches the structure of the control. The state is a standalone value + * or a form state object with both a value and a disabled status. + * + * @usageNotes + * ### Reset the values in a form array + * + * ```ts + * const arr = new FormArray([ + * new FormControl(), + * new FormControl() + * ]); + * arr.reset(['name', 'last name']); + * + * console.log(arr.value); // ['name', 'last name'] + * ``` + * + * ### Reset the values in a form array and the disabled status for the first control + * + * ```ts + * arr.reset([ + * {value: 'name', disabled: true}, + * 'last' + * ]); + * + * console.log(arr.value); // ['last'] + * console.log(arr.at(0).status); // 'DISABLED' + * ``` + * + * @param value Array of values for the controls + * @param options Configure options that determine how the control propagates changes and + * emits events after the value changes + * + * * `onlySelf`: When true, each change only affects this control, and not its parent. Default + * is false. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` + * observables emit events with the latest status and value when the control is reset. + * When false, no events are emitted. + * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity + * updateValueAndValidity} method. + */ + reset(value = [], options = {}) { + this._forEachChild((control, index) => { + control.reset(value[index], { + onlySelf: true, + emitEvent: options.emitEvent + }); + }); + this._updatePristine(options, this); + this._updateTouched(options, this); + this.updateValueAndValidity(options); + } + /** + * The aggregate value of the array, including any disabled controls. + * + * Reports all values regardless of disabled status. + */ + getRawValue() { + return this.controls.map((control) => control.getRawValue()); + } + /** + * Remove all controls in the `FormArray`. + * + * @param options Specifies whether this FormArray instance should emit events after all + * controls are removed. + * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and + * `valueChanges` observables emit events with the latest status and value when all controls + * in this FormArray instance are removed. When false, no events are emitted. + * + * @usageNotes + * ### Remove all elements from a FormArray + * + * ```ts + * const arr = new FormArray([ + * new FormControl(), + * new FormControl() + * ]); + * console.log(arr.length); // 2 + * + * arr.clear(); + * console.log(arr.length); // 0 + * ``` + * + * It's a simpler and more efficient alternative to removing all elements one by one: + * + * ```ts + * const arr = new FormArray([ + * new FormControl(), + * new FormControl() + * ]); + * + * while (arr.length) { + * arr.removeAt(0); + * } + * ``` + */ + clear(options = {}) { + if (this.controls.length < 1) return; + this._forEachChild((control) => control._registerOnCollectionChange(() => { + })); + this.controls.splice(0); + this.updateValueAndValidity({ + emitEvent: options.emitEvent + }); + } + /** + * Adjusts a negative index by summing it with the length of the array. For very negative + * indices, the result may remain negative. + * @internal + */ + _adjustIndex(index) { + return index < 0 ? index + this.length : index; + } + /** @internal */ + _syncPendingControls() { + let subtreeUpdated = this.controls.reduce((updated, child) => { + return child._syncPendingControls() ? true : updated; + }, false); + if (subtreeUpdated) this.updateValueAndValidity({ + onlySelf: true + }); + return subtreeUpdated; + } + /** @internal */ + _forEachChild(cb) { + this.controls.forEach((control, index) => { + cb(control, index); + }); + } + /** @internal */ + _updateValue() { + this.value = this.controls.filter((control) => control.enabled || this.disabled).map((control) => control.value); + } + /** @internal */ + _anyControls(condition) { + return this.controls.some((control) => control.enabled && condition(control)); + } + /** @internal */ + _setUpControls() { + this._forEachChild((control) => this._registerControl(control)); + } + /** @internal */ + _allControlsDisabled() { + for (const control of this.controls) { + if (control.enabled) return false; + } + return this.controls.length > 0 || this.disabled; + } + _registerControl(control) { + control.setParent(this); + control._registerOnCollectionChange(this._onCollectionChange); + } + /** @internal */ + _find(name) { + return this.at(name) ?? null; + } +}; +var UntypedFormArray = FormArray; +var isFormArray = (control) => control instanceof FormArray; +function isAbstractControlOptions(options) { + return !!options && (options.asyncValidators !== void 0 || options.validators !== void 0 || options.updateOn !== void 0); +} +var FormBuilder = class _FormBuilder { + useNonNullable = false; + /** + * @description + * Returns a FormBuilder in which automatically constructed `FormControl` elements + * have `{nonNullable: true}` and are non-nullable. + * + * **Constructing non-nullable controls** + * + * When constructing a control, it will be non-nullable, and will reset to its initial value. + * + * ```ts + * let nnfb = new FormBuilder().nonNullable; + * let name = nnfb.control('Alex'); // FormControl + * name.reset(); + * console.log(name); // 'Alex' + * ``` + * + * **Constructing non-nullable groups or arrays** + * + * When constructing a group or array, all automatically created inner controls will be + * non-nullable, and will reset to their initial values. + * + * ```ts + * let nnfb = new FormBuilder().nonNullable; + * let name = nnfb.group({who: 'Alex'}); // FormGroup<{who: FormControl}> + * name.reset(); + * console.log(name); // {who: 'Alex'} + * ``` + * **Constructing *nullable* fields on groups or arrays** + * + * It is still possible to have a nullable field. In particular, any `FormControl` which is + * *already* constructed will not be altered. For example: + * + * ```ts + * let nnfb = new FormBuilder().nonNullable; + * // FormGroup<{who: FormControl}> + * let name = nnfb.group({who: new FormControl('Alex')}); + * name.reset(); console.log(name); // {who: null} + * ``` + * + * Because the inner control is constructed explicitly by the caller, the builder has + * no control over how it is created, and cannot exclude the `null`. + */ + get nonNullable() { + const nnfb = new _FormBuilder(); + nnfb.useNonNullable = true; + return nnfb; + } + group(controls, options = null) { + const reducedControls = this._reduceControls(controls); + let newOptions = {}; + if (isAbstractControlOptions(options)) { + newOptions = options; + } else if (options !== null) { + newOptions.validators = options.validator; + newOptions.asyncValidators = options.asyncValidator; + } + return new FormGroup(reducedControls, newOptions); + } + /** + * @description + * Constructs a new `FormRecord` instance. Accepts a single generic argument, which is an object + * containing all the keys and corresponding inner control types. + * + * @param controls A collection of child controls. The key for each child is the name + * under which it is registered. + * + * @param options Configuration options object for the `FormRecord`. The object should have the + * `AbstractControlOptions` type and might contain the following fields: + * * `validators`: A synchronous validator function, or an array of validator functions. + * * `asyncValidators`: A single async validator or array of async validator functions. + * * `updateOn`: The event upon which the control should be updated (options: 'change' | 'blur' + * | submit'). + */ + record(controls, options = null) { + const reducedControls = this._reduceControls(controls); + return new FormRecord(reducedControls, options); + } + /** + * @description + * Constructs a new `FormControl` with the given state, validators and options. Sets + * `{nonNullable: true}` in the options to get a non-nullable control. Otherwise, the + * control will be nullable. Accepts a single generic argument, which is the type of the + * control's value. + * + * @param formState Initializes the control with an initial state value, or + * with an object that contains both a value and a disabled status. + * + * @param validatorOrOpts A synchronous validator function, or an array of + * such functions, or a `FormControlOptions` object that contains + * validation functions and a validation trigger. + * + * @param asyncValidator A single async validator or array of async validator + * functions. + * + * @usageNotes + * + * ### Initialize a control as disabled + * + * The following example returns a control with an initial value in a disabled state. + * + * {@example forms/ts/formBuilder/form_builder_example.ts region='disabled-control'} + */ + control(formState, validatorOrOpts, asyncValidator) { + let newOptions = {}; + if (!this.useNonNullable) { + return new FormControl(formState, validatorOrOpts, asyncValidator); + } + if (isAbstractControlOptions(validatorOrOpts)) { + newOptions = validatorOrOpts; + } else { + newOptions.validators = validatorOrOpts; + newOptions.asyncValidators = asyncValidator; + } + return new FormControl(formState, __spreadProps(__spreadValues({}, newOptions), { + nonNullable: true + })); + } + /** + * Constructs a new `FormArray` from the given array of configurations, + * validators and options. Accepts a single generic argument, which is the type of each control + * inside the array. + * + * @param controls An array of child controls or control configs. Each child control is given an + * index when it is registered. + * + * @param validatorOrOpts A synchronous validator function, or an array of such functions, or an + * `AbstractControlOptions` object that contains + * validation functions and a validation trigger. + * + * @param asyncValidator A single async validator or array of async validator functions. + */ + array(controls, validatorOrOpts, asyncValidator) { + const createdControls = controls.map((c) => this._createControl(c)); + return new FormArray(createdControls, validatorOrOpts, asyncValidator); + } + /** @internal */ + _reduceControls(controls) { + const createdControls = {}; + Object.keys(controls).forEach((controlName) => { + createdControls[controlName] = this._createControl(controls[controlName]); + }); + return createdControls; + } + /** @internal */ + _createControl(controls) { + if (controls instanceof FormControl) { + return controls; + } else if (controls instanceof AbstractControl) { + return controls; + } else if (Array.isArray(controls)) { + const value = controls[0]; + const validator = controls.length > 1 ? controls[1] : null; + const asyncValidator = controls.length > 2 ? controls[2] : null; + return this.control(value, validator, asyncValidator); + } else { + return this.control(controls); + } + } + static ɵfac = function FormBuilder_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _FormBuilder)(); + }; + static ɵprov = ɵɵdefineInjectable({ + token: _FormBuilder, + factory: _FormBuilder.ɵfac, + providedIn: "root" + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(FormBuilder, [{ + type: Injectable, + args: [{ + providedIn: "root" + }] + }], null, null); +})(); +var NonNullableFormBuilder = class _NonNullableFormBuilder { + static ɵfac = function NonNullableFormBuilder_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _NonNullableFormBuilder)(); + }; + static ɵprov = ɵɵdefineInjectable({ + token: _NonNullableFormBuilder, + factory: () => (() => inject(FormBuilder).nonNullable)(), + providedIn: "root" + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NonNullableFormBuilder, [{ + type: Injectable, + args: [{ + providedIn: "root", + useFactory: () => inject(FormBuilder).nonNullable + }] + }], null, null); +})(); +var UntypedFormBuilder = class _UntypedFormBuilder extends FormBuilder { + group(controlsConfig, options = null) { + return super.group(controlsConfig, options); + } + /** + * Like `FormBuilder#control`, except the resulting control is untyped. + */ + control(formState, validatorOrOpts, asyncValidator) { + return super.control(formState, validatorOrOpts, asyncValidator); + } + /** + * Like `FormBuilder#array`, except the resulting array is untyped. + */ + array(controlsConfig, validatorOrOpts, asyncValidator) { + return super.array(controlsConfig, validatorOrOpts, asyncValidator); + } + static ɵfac = /* @__PURE__ */ (() => { + let ɵUntypedFormBuilder_BaseFactory; + return function UntypedFormBuilder_Factory(__ngFactoryType__) { + return (ɵUntypedFormBuilder_BaseFactory || (ɵUntypedFormBuilder_BaseFactory = ɵɵgetInheritedFactory(_UntypedFormBuilder)))(__ngFactoryType__ || _UntypedFormBuilder); + }; + })(); + static ɵprov = ɵɵdefineInjectable({ + token: _UntypedFormBuilder, + factory: _UntypedFormBuilder.ɵfac, + providedIn: "root" + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(UntypedFormBuilder, [{ + type: Injectable, + args: [{ + providedIn: "root" + }] + }], null, null); +})(); +var VERSION = new Version("20.2.4"); +var FormsModule = class _FormsModule { + /** + * @description + * Provides options for configuring the forms module. + * + * @param opts An object of configuration options + * * `callSetDisabledState` Configures whether to `always` call `setDisabledState`, which is more + * correct, or to only call it `whenDisabled`, which is the legacy behavior. + */ + static withConfig(opts) { + return { + ngModule: _FormsModule, + providers: [{ + provide: CALL_SET_DISABLED_STATE, + useValue: opts.callSetDisabledState ?? setDisabledStateDefault + }] + }; + } + static ɵfac = function FormsModule_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _FormsModule)(); + }; + static ɵmod = ɵɵdefineNgModule({ + type: _FormsModule, + declarations: [NgModel, NgModelGroup, NgForm], + exports: [ɵInternalFormsSharedModule, NgModel, NgModelGroup, NgForm] + }); + static ɵinj = ɵɵdefineInjector({ + imports: [ɵInternalFormsSharedModule] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(FormsModule, [{ + type: NgModule, + args: [{ + declarations: TEMPLATE_DRIVEN_DIRECTIVES, + exports: [ɵInternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES] + }] + }], null, null); +})(); +var ReactiveFormsModule = class _ReactiveFormsModule { + /** + * @description + * Provides options for configuring the reactive forms module. + * + * @param opts An object of configuration options + * * `warnOnNgModelWithFormControl` Configures when to emit a warning when an `ngModel` + * binding is used with reactive form directives. + * * `callSetDisabledState` Configures whether to `always` call `setDisabledState`, which is more + * correct, or to only call it `whenDisabled`, which is the legacy behavior. + */ + static withConfig(opts) { + return { + ngModule: _ReactiveFormsModule, + providers: [{ + provide: NG_MODEL_WITH_FORM_CONTROL_WARNING, + useValue: opts.warnOnNgModelWithFormControl ?? "always" + }, { + provide: CALL_SET_DISABLED_STATE, + useValue: opts.callSetDisabledState ?? setDisabledStateDefault + }] + }; + } + static ɵfac = function ReactiveFormsModule_Factory(__ngFactoryType__) { + return new (__ngFactoryType__ || _ReactiveFormsModule)(); + }; + static ɵmod = ɵɵdefineNgModule({ + type: _ReactiveFormsModule, + declarations: [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName], + exports: [ɵInternalFormsSharedModule, FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName] + }); + static ɵinj = ɵɵdefineInjector({ + imports: [ɵInternalFormsSharedModule] + }); +}; +(() => { + (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ReactiveFormsModule, [{ + type: NgModule, + args: [{ + declarations: [REACTIVE_DRIVEN_DIRECTIVES], + exports: [ɵInternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES] + }] + }], null, null); +})(); +export { + AbstractControl, + AbstractControlDirective, + AbstractFormGroupDirective, + COMPOSITION_BUFFER_MODE, + CheckboxControlValueAccessor, + CheckboxRequiredValidator, + ControlContainer, + ControlEvent, + DefaultValueAccessor, + EmailValidator, + FormArray, + FormArrayName, + FormBuilder, + FormControl, + FormControlDirective, + FormControlName, + FormGroup, + FormGroupDirective, + FormGroupName, + FormRecord, + FormResetEvent, + FormSubmittedEvent, + FormsModule, + MaxLengthValidator, + MaxValidator, + MinLengthValidator, + MinValidator, + NG_ASYNC_VALIDATORS, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + NgControl, + NgControlStatus, + NgControlStatusGroup, + NgForm, + NgModel, + NgModelGroup, + NgSelectOption, + NonNullableFormBuilder, + NumberValueAccessor, + PatternValidator, + PristineChangeEvent, + RadioControlValueAccessor, + RangeValueAccessor, + ReactiveFormsModule, + RequiredValidator, + SelectControlValueAccessor, + SelectMultipleControlValueAccessor, + StatusChangeEvent, + TouchedChangeEvent, + UntypedFormArray, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + VERSION, + Validators, + ValueChangeEvent, + isFormArray, + isFormControl, + isFormGroup, + isFormRecord, + ɵInternalFormsSharedModule, + ɵNgNoValidate, + ɵNgSelectMultipleOption +}; +/*! Bundled license information: + +@angular/forms/fesm2022/forms.mjs: + (** + * @license Angular v20.2.4 + * (c) 2010-2025 Google LLC. https://angular.io/ + * License: MIT + *) +*/ +//# sourceMappingURL=@angular_forms.js.map diff --git a/.angular/cache/20.2.2/app/vite/deps/@angular_forms.js.map b/.angular/cache/20.2.2/app/vite/deps/@angular_forms.js.map new file mode 100644 index 0000000..ed5fb50 --- /dev/null +++ b/.angular/cache/20.2.2/app/vite/deps/@angular_forms.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../../../../../node_modules/@angular/forms/fesm2022/forms.mjs"], + "sourcesContent": ["/**\n * @license Angular v20.2.4\n * (c) 2010-2025 Google LLC. https://angular.io/\n * License: MIT\n */\n\nimport * as i0 from '@angular/core';\nimport { Directive, InjectionToken, forwardRef, Optional, Inject, ɵisPromise as _isPromise, ɵisSubscribable as _isSubscribable, ɵRuntimeError as _RuntimeError, Self, untracked, computed, signal, EventEmitter, Input, Host, SkipSelf, booleanAttribute, ChangeDetectorRef, Output, Injectable, inject, ApplicationRef, DestroyRef, afterNextRender, NgModule, Version } from '@angular/core';\nimport { ɵgetDOM as _getDOM } from '@angular/common';\nimport { forkJoin, from, Subject } from 'rxjs';\nimport { map } from 'rxjs/operators';\n\n/**\n * Base class for all ControlValueAccessor classes defined in Forms package.\n * Contains common logic and utility functions.\n *\n * Note: this is an *internal-only* class and should not be extended or used directly in\n * applications code.\n */\nclass BaseControlValueAccessor {\n _renderer;\n _elementRef;\n /**\n * The registered callback function called when a change or input event occurs on the input\n * element.\n * @docs-private\n */\n onChange = _ => {};\n /**\n * The registered callback function called when a blur event occurs on the input element.\n * @docs-private\n */\n onTouched = () => {};\n constructor(_renderer, _elementRef) {\n this._renderer = _renderer;\n this._elementRef = _elementRef;\n }\n /**\n * Helper method that sets a property on a target element using the current Renderer\n * implementation.\n * @docs-private\n */\n setProperty(key, value) {\n this._renderer.setProperty(this._elementRef.nativeElement, key, value);\n }\n /**\n * Registers a function called when the control is touched.\n * @docs-private\n */\n registerOnTouched(fn) {\n this.onTouched = fn;\n }\n /**\n * Registers a function called when the control value changes.\n * @docs-private\n */\n registerOnChange(fn) {\n this.onChange = fn;\n }\n /**\n * Sets the \"disabled\" property on the range input element.\n * @docs-private\n */\n setDisabledState(isDisabled) {\n this.setProperty('disabled', isDisabled);\n }\n static ɵfac = function BaseControlValueAccessor_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || BaseControlValueAccessor)(i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i0.ElementRef));\n };\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: BaseControlValueAccessor\n });\n}\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && i0.ɵsetClassMetadata(BaseControlValueAccessor, [{\n type: Directive\n }], () => [{\n type: i0.Renderer2\n }, {\n type: i0.ElementRef\n }], null);\n})();\n/**\n * Base class for all built-in ControlValueAccessor classes (except DefaultValueAccessor, which is\n * used in case no other CVAs can be found). We use this class to distinguish between default CVA,\n * built-in CVAs and custom CVAs, so that Forms logic can recognize built-in CVAs and treat custom\n * ones with higher priority (when both built-in and custom CVAs are present).\n *\n * Note: this is an *internal-only* class and should not be extended or used directly in\n * applications code.\n */\nclass BuiltInControlValueAccessor extends BaseControlValueAccessor {\n static ɵfac = /* @__PURE__ */(() => {\n let ɵBuiltInControlValueAccessor_BaseFactory;\n return function BuiltInControlValueAccessor_Factory(__ngFactoryType__) {\n return (ɵBuiltInControlValueAccessor_BaseFactory || (ɵBuiltInControlValueAccessor_BaseFactory = i0.ɵɵgetInheritedFactory(BuiltInControlValueAccessor)))(__ngFactoryType__ || BuiltInControlValueAccessor);\n };\n })();\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: BuiltInControlValueAccessor,\n features: [i0.ɵɵInheritDefinitionFeature]\n });\n}\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && i0.ɵsetClassMetadata(BuiltInControlValueAccessor, [{\n type: Directive\n }], null, null);\n})();\n/**\n * Used to provide a `ControlValueAccessor` for form controls.\n *\n * See `DefaultValueAccessor` for how to implement one.\n *\n * @publicApi\n */\nconst NG_VALUE_ACCESSOR = new InjectionToken(ngDevMode ? 'NgValueAccessor' : '');\nconst CHECKBOX_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => CheckboxControlValueAccessor),\n multi: true\n};\n/**\n * @description\n * A `ControlValueAccessor` for writing a value and listening to changes on a checkbox input\n * element.\n *\n * @usageNotes\n *\n * ### Using a checkbox with a reactive form.\n *\n * The following example shows how to use a checkbox with a reactive form.\n *\n * ```ts\n * const rememberLoginControl = new FormControl();\n * ```\n *\n * ```html\n * \n * ```\n *\n * @ngModule ReactiveFormsModule\n * @ngModule FormsModule\n * @publicApi\n */\nclass CheckboxControlValueAccessor extends BuiltInControlValueAccessor {\n /**\n * Sets the \"checked\" property on the input element.\n * @docs-private\n */\n writeValue(value) {\n this.setProperty('checked', value);\n }\n static ɵfac = /* @__PURE__ */(() => {\n let ɵCheckboxControlValueAccessor_BaseFactory;\n return function CheckboxControlValueAccessor_Factory(__ngFactoryType__) {\n return (ɵCheckboxControlValueAccessor_BaseFactory || (ɵCheckboxControlValueAccessor_BaseFactory = i0.ɵɵgetInheritedFactory(CheckboxControlValueAccessor)))(__ngFactoryType__ || CheckboxControlValueAccessor);\n };\n })();\n static ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CheckboxControlValueAccessor,\n selectors: [[\"input\", \"type\", \"checkbox\", \"formControlName\", \"\"], [\"input\", \"type\", \"checkbox\", \"formControl\", \"\"], [\"input\", \"type\", \"checkbox\", \"ngModel\", \"\"]],\n hostBindings: function CheckboxControlValueAccessor_HostBindings(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵlistener(\"change\", function CheckboxControlValueAccessor_change_HostBindingHandler($event) {\n return ctx.onChange($event.target.checked);\n })(\"blur\", function CheckboxControlValueAccessor_blur_HostBindingHandler() {\n return ctx.onTouched();\n });\n }\n },\n standalone: false,\n features: [i0.ɵɵProvidersFeature([CHECKBOX_VALUE_ACCESSOR]), i0.ɵɵInheritDefinitionFeature]\n });\n}\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && i0.ɵsetClassMetadata(CheckboxControlValueAccessor, [{\n type: Directive,\n args: [{\n selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',\n host: {\n '(change)': 'onChange($any($event.target).checked)',\n '(blur)': 'onTouched()'\n },\n providers: [CHECKBOX_VALUE_ACCESSOR],\n standalone: false\n }]\n }], null, null);\n})();\nconst DEFAULT_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DefaultValueAccessor),\n multi: true\n};\n/**\n * We must check whether the agent is Android because composition events\n * behave differently between iOS and Android.\n */\nfunction _isAndroid() {\n const userAgent = _getDOM() ? _getDOM().getUserAgent() : '';\n return /android (\\d+)/.test(userAgent.toLowerCase());\n}\n/**\n * @description\n * Provide this token to control if form directives buffer IME input until\n * the \"compositionend\" event occurs.\n * @publicApi\n */\nconst COMPOSITION_BUFFER_MODE = new InjectionToken(ngDevMode ? 'CompositionEventMode' : '');\n/**\n * The default `ControlValueAccessor` for writing a value and listening to changes on input\n * elements. The accessor is used by the `FormControlDirective`, `FormControlName`, and\n * `NgModel` directives.\n *\n *\n * @usageNotes\n *\n * ### Using the default value accessor\n *\n * The following example shows how to use an input element that activates the default value accessor\n * (in this case, a text field).\n *\n * ```ts\n * const firstNameControl = new FormControl();\n * ```\n *\n * ```html\n * \n * ```\n *\n * This value accessor is used by default for `` and ` +
+ + +
+ + + + diff --git a/src/components/header/header.component.ts b/src/components/header/header.component.ts new file mode 100644 index 0000000..4669373 --- /dev/null +++ b/src/components/header/header.component.ts @@ -0,0 +1,550 @@ +import { ChangeDetectionStrategy, Component, computed, inject, signal, Output, EventEmitter, HostListener, ViewChild, ElementRef } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Router, RouterLink, NavigationEnd } from '@angular/router'; +import { InstanceService, Provider } from '../../services/instance.service'; +import { FormsModule } from '@angular/forms'; +import { AuthService } from '../../services/auth.service'; +import { UserService } from '../../services/user.service'; +import { firstValueFrom } from 'rxjs'; +import { TranslatePipe } from '../../pipes/translate.pipe'; +import { I18nService } from '../../services/i18n.service'; +import { ThemesService } from '../../services/themes.service'; +import { HistoryService, SearchHistoryItem } from '../../services/history.service'; + +@Component({ + selector: 'app-header', + templateUrl: './header.component.html', + standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + RouterLink, + CommonModule, + FormsModule, + TranslatePipe + ] +}) +export class HeaderComponent { + private router = inject(Router); + instances = inject(InstanceService); + private auth = inject(AuthService); + private userService = inject(UserService); + private i18n = inject(I18nService); + private themes = inject(ThemesService); + private history = inject(HistoryService); + + @ViewChild('searchInput', { static: false }) searchInputRef?: ElementRef; + @ViewChild('userMenuContainer', { static: false }) userMenuContainerRef?: ElementRef; + + searchQuery = ''; + editingPeerTubeInstances = signal(false); + peerTubeInstancesInput = ''; + + // Search suggestions dropdown state + suggestionsOpen = signal(false); + recentSearches = signal([]); + highlightedIndex = signal(-1); + // Suggestion item shape: history vs generated + readonly suggestionItems = computed<{ text: string; source: 'history' | 'generated' }[]>(() => { + type Item = { text: string; source: 'history' | 'generated' }; + const q = (this.searchQuery || '').trim(); + const provider = this.selectedProvider(); + const fromHistory = (this.recentSearches() || []) + .map(it => (it.query || '').trim()) + .filter(Boolean); + + // 1) Base list from history + let historyList: string[]; + if (!q) { + historyList = fromHistory.slice(0, 15); + } else { + const lower = q.toLowerCase(); + historyList = fromHistory.filter(txt => txt.toLowerCase().includes(lower)).slice(0, 15); + } + + const items: Item[] = historyList.map(text => ({ text, source: 'history' })); + + // 2) If we have fewer than 15, fill with generated suggestions + if (items.length < 15) { + const need = 15 - items.length; + const generated = this.generateQuerySuggestions(q, provider); + // Avoid duplicates with history + const existing = new Set(items.map(i => i.text.toLowerCase())); + for (const g of generated) { + const t = (g || '').trim(); + if (!t) continue; + if (existing.has(t.toLowerCase())) continue; + items.push({ text: t, source: 'generated' }); + if (items.length >= 15) break; + } + } + + // Reset highlight if list size changes or becomes empty + const prev = this.highlightedIndex(); + if (prev >= items.length) this.highlightedIndex.set(items.length - 1); + if (items.length === 0) this.highlightedIndex.set(-1); + return items; + }); + + // Generate query suggestions based on the current text and provider + private generateQuerySuggestions(q: string, provider: string | null): string[] { + const base = (q || '').trim(); + const suggestions: string[] = []; + + // If nothing typed yet, propose popular generic queries per provider context + if (!base) { + // Lightweight provider-tailored seeds + const common = [ + 'live', 'news', 'best of', 'highlights', 'playlist', 'remix', 'cover', 'tutorial', 'review' + ]; + if (provider === 'youtube') { + suggestions.push('trending', 'documentary', 'mix', 'lyrics', 'official video'); + } else if (provider === 'peertube') { + suggestions.push('open source', 'conference', 'self-hosted'); + } + suggestions.push(...common); + return suggestions; + } + + // Heuristics: variants that typically help discovery + const quoted = `"${base}"`; + const year = new Date().getFullYear(); + const tokens = [ + quoted, + `${base} official`, + `${base} live`, + `${base} lyrics`, + `${base} remix`, + `${base} cover`, + `${base} tutorial`, + `${base} review`, + `${base} full album`, + `${base} best of`, + `${base} ${year}`, + `${base} ${year - 1}` + ]; + + if (provider === 'youtube') { + tokens.push(`${base} playlist`, `${base} 4k`, `${base} short`); + } + if (provider === 'rumble') { + tokens.push(`${base} highlights`, `${base} podcast`); + } + + // Keep unique and meaningful + const seen = new Set(); + for (const t of tokens) { + const key = t.toLowerCase(); + if (!seen.has(key)) { + seen.add(key); + suggestions.push(t); + } + if (suggestions.length >= 20) break; + } + return suggestions; + } + + readonly providers = computed(() => this.instances.providers()); + readonly selectedProvider = computed(() => this.instances.selectedProvider()); + readonly user = computed(() => this.auth.currentUser()); + + // Provider context read from current URL query param (?provider=...) + providerContext = signal(null); + providerContextLabel = computed(() => { + const ctx = this.providerContext(); + if (!ctx) return null; + const p = this.providers().find(x => x.id === ctx); + return p?.label || ctx; + }); + + // Theme management (global/local) + themeOptions = ['system', 'light', 'dark', 'black', 'blue']; + currentTheme = signal((() => { + try { return localStorage.getItem('newtube.theme') || 'system'; } catch { return 'system'; } + })()); + + // Login/Register modals state + loginOpen = signal(false); + registerOpen = signal(false); + loginUsername = signal(''); + loginPassword = signal(''); + rememberMe = signal(true); + registerUsername = signal(''); + registerPassword = signal(''); + registerEmail = signal(''); + authError = signal(null); + userMenuOpen = signal(false); + + // Sidebar toggle (emits to parent AppComponent) + @Output() menuToggle = new EventEmitter(); + + onSubmitSearch(ev: Event, input: HTMLInputElement) { + ev.preventDefault(); + const q = input.value.trim(); + if (!q) return; + const provider = this.selectedProvider(); + const theme = this.themes.activeSlug(); + const qp: any = { q, provider }; + if (theme) qp.theme = theme; + this.router.navigate(['/search'], { queryParams: qp }); + } + + // Open suggestions and load last 15 searches when focusing the input + onSearchFocus() { + this.suggestionsOpen.set(true); + this.loadRecentSearches(); + this.highlightedIndex.set(-1); + } + + // Keep suggestions open and update searchQuery as user types + onSearchInput(input: HTMLInputElement) { + this.searchQuery = input.value; + if (!this.suggestionsOpen()) { + this.suggestionsOpen.set(true); + } + // Force refresh of suggestions by updating the signal + this.recentSearches.update(searches => [...searches]); + this.highlightedIndex.set(-1); + } + + // Delay closing to allow click on a suggestion + onSearchBlur() { + setTimeout(() => this.suggestionsOpen.set(false), 150); + } + + // Pick a suggestion: fill input and submit navigation + pickSuggestion(text: string, input: HTMLInputElement) { + input.value = text; + this.searchQuery = text; + // Submit same as pressing Enter + const provider = this.selectedProvider(); + const theme = this.themes.activeSlug(); + const qp: any = { q: text, provider }; + if (theme) qp.theme = theme; + this.router.navigate(['/search'], { queryParams: qp }); + this.suggestionsOpen.set(false); + } + + // Keyboard navigation for suggestions + onSearchKeydown(ev: KeyboardEvent, input: HTMLInputElement) { + const items = this.suggestionItems(); + if (!items || items.length === 0) return; + const max = items.length - 1; + const current = this.highlightedIndex(); + if (ev.key === 'ArrowDown') { + ev.preventDefault(); + const next = Math.min(max, current + 1); + this.highlightedIndex.set(next < 0 ? 0 : next); + } else if (ev.key === 'ArrowUp') { + ev.preventDefault(); + const next = Math.max(-1, current - 1); + this.highlightedIndex.set(next); + } else if (ev.key === 'Enter') { + if (current >= 0 && current <= max) { + ev.preventDefault(); + const chosen = items[current]?.text; + if (chosen) this.pickSuggestion(chosen, input); + } + } else if (ev.key === 'Escape') { + this.suggestionsOpen.set(false); + } + } + + // Theme helpers for styling based on current theme + getCurrentTheme(): string { + return this.currentTheme() || 'system'; + } + + isLightTheme(): boolean { + const t = this.getCurrentTheme(); + return t === 'light' || t === 'system'; + } + + isDarkTheme(): boolean { + const t = this.getCurrentTheme(); + return t === 'dark'; + } + + isBlackTheme(): boolean { + const t = this.getCurrentTheme(); + return t === 'black'; + } + + isBlueTheme(): boolean { + const t = this.getCurrentTheme(); + return t === 'blue'; + } + + getThemeClasses(): { [key: string]: boolean } { + const theme = this.getCurrentTheme(); + return { + 'theme-light': theme === 'light' || theme === 'system', + 'theme-dark': theme === 'dark', + 'theme-black': theme === 'black', + 'theme-blue': theme === 'blue' + }; + } + + // Helper to show the divider before the first generated item + isFirstGenerated(index: number): boolean { + const arr = this.suggestionItems(); + if (!arr || index < 0 || index >= arr.length) return false; + if (arr[index]?.source !== 'generated') return false; + return index === 0 || arr[index - 1]?.source !== 'generated'; + } + + private loadRecentSearches() { + try { + this.history.getSearchHistory(15).subscribe({ + next: (items) => { + // API likely returns newest first; ensure we keep order and dedupe by query + this.recentSearches.set(items || []); + }, + error: () => {} + }); + } catch {} + } + + ngOnInit() { + // Initialize and keep provider context in sync with URL + this.updateProviderContextFromUrl(this.router.url); + this.router.events.subscribe(evt => { + if (evt instanceof NavigationEnd) { + this.updateProviderContextFromUrl(evt.urlAfterRedirects || evt.url); + } + }); + } + + private updateProviderContextFromUrl(url: string) { + try { + // Normalize to portion after '#', if present (hash routing) + const hashIdx = url.indexOf('#'); + const afterHash = hashIdx >= 0 ? url.substring(hashIdx + 1) : url; + // Prefer query param ?provider=... + const qIdx = afterHash.indexOf('?'); + const query = qIdx >= 0 ? afterHash.substring(qIdx + 1) : ''; + const params = new URLSearchParams(query); + let provider = (params.get('provider') || '').trim() as Provider; + + // If not provided via query, try path format /p/:provider/... (supports hash and non-hash routing) + if (!provider) { + // Normalize to path without query/hash prefix symbols + const pathOnly = (qIdx >= 0 ? afterHash.substring(0, qIdx) : afterHash) || ''; + const noHash = pathOnly; // already removed above + const segs = noHash.split('/').filter(s => s.length > 0); + // Look for pattern ['p', ':provider', ...] + const pIdx = segs.indexOf('p'); + if (pIdx >= 0 && segs.length > pIdx + 1) { + provider = segs[pIdx + 1] as Provider; + } + } + + // Validate against known providers list; if none and we're on Shorts, fall back to selected provider + const known = this.providers().map(p => p.id); + if (provider && known.includes(provider)) { + this.providerContext.set(provider); + } else { + // If current path looks like '/shorts' (hash routing already normalized above) + const pathOnly = (qIdx >= 0 ? afterHash.substring(0, qIdx) : afterHash) || ''; + const segs = pathOnly.split('/').filter(s => s.length > 0); + if (segs.length > 0 && segs[0] === 'shorts') { + const fallback = this.selectedProvider(); + if (fallback && known.includes(fallback)) { + this.providerContext.set(fallback); + return; + } + } + this.providerContext.set(null); + } + } catch { + this.providerContext.set(null); + } + } + + // When the native clear (X) on a search input is clicked, browsers fire a 'search' event. + // If the field becomes empty, navigate back to Home. + onSearchCleared(input: HTMLInputElement) { + const q = (input?.value || '').trim(); + if (!q) { + this.router.navigate(['/']); + } + } + + focusSearch() { + try { + const el = this.searchInputRef?.nativeElement; + if (el) { el.focus(); el.select(); } + } catch {} + } + + @HostListener('document:keydown', ['$event']) + handleGlobalKeydown(ev: KeyboardEvent) { + const isInput = (ev.target as HTMLElement)?.closest('input, textarea, [contenteditable="true"]'); + // Ctrl/Cmd+K focuses search + if ((ev.key === 'k' || ev.key === 'K') && (ev.ctrlKey || ev.metaKey)) { + ev.preventDefault(); + this.focusSearch(); + return; + } + // '/' focuses search when not typing in another input + if (ev.key === '/' && !isInput) { + ev.preventDefault(); + this.focusSearch(); + return; + } + // Escape blurs search + if (ev.key === 'Escape') { + const el = this.searchInputRef?.nativeElement; + if (el && document.activeElement === el) { + (document.activeElement as HTMLElement)?.blur(); + } + } + } + + onProviderChange(event: Event) { + const selectedProvider = (event.target as HTMLSelectElement).value as Provider; + this.instances.setSelectedProvider(selectedProvider); + } + + toggleUserMenu() { + this.userMenuOpen.update(v => !v); + } + + @HostListener('document:click', ['$event']) + onDocumentClick(ev: MouseEvent) { + if (!this.userMenuOpen()) return; + const container = this.userMenuContainerRef?.nativeElement; + const target = ev.target as Node | null; + if (container && target && !container.contains(target)) { + this.userMenuOpen.set(false); + } + } + + onPeerTubeInstanceChange(event: Event) { + const selectedInstance = (event.target as HTMLSelectElement).value; + this.instances.setActivePeerTubeInstance(selectedInstance); + } + + editPeerTubeInstances() { + this.peerTubeInstancesInput = this.instances.peerTubeInstances().join('\n'); + this.editingPeerTubeInstances.set(true); + } + + savePeerTubeInstances() { + const instances = this.peerTubeInstancesInput.split('\n').map(i => i.trim()).filter(i => i.length > 0); + this.instances.setPeerTubeInstances(instances); + if (!instances.includes(this.instances.activePeerTubeInstance())) { + this.instances.setActivePeerTubeInstance(instances[0] || ''); + } + this.editingPeerTubeInstances.set(false); + } + + onThemeChange(event: Event) { + const value = (event.target as HTMLSelectElement | null)?.value || 'system'; + this.setTheme(value); + } + + setTheme(value: string) { + this.currentTheme.set(value); + try { + document.documentElement.setAttribute('data-theme', value); + localStorage.setItem('newtube.theme', value); + } catch {} + // If logged in, persist to backend preferences (fire-and-forget) + if (this.user()) { + try { this.userService.updatePreferences({ theme: value }).subscribe({ next: () => {}, error: () => {} }); } catch {} + } + } + + cycleTheme() { + const order = this.themeOptions; + const cur = this.currentTheme(); + const idx = Math.max(0, order.indexOf(cur)); + const nextVal = order[(idx + 1) % order.length]; + this.setTheme(nextVal); + } + + // Auth actions + openLogin() { this.clearAuthForms(); this.loginOpen.set(true); } + openRegister() { this.clearAuthForms(); this.registerOpen.set(true); } + closeModals() { this.loginOpen.set(false); this.registerOpen.set(false); this.authError.set(null); } + + private clearAuthForms() { + this.loginUsername.set(''); + this.loginPassword.set(''); + this.rememberMe.set(true); + this.registerUsername.set(''); + this.registerPassword.set(''); + this.registerEmail.set(''); + this.authError.set(null); + } + + async onSubmitLogin(ev: Event, u?: HTMLInputElement, p?: HTMLInputElement, rm?: HTMLInputElement) { + ev.preventDefault(); + this.authError.set(null); + try { + const username = (u?.value ?? this.loginUsername()).trim(); + const password = p?.value ?? this.loginPassword(); + const remember = (rm?.checked != null) ? rm.checked : this.rememberMe(); + await firstValueFrom(this.auth.login(username, password, remember)); + // Load preferences and apply immediately + const prefs = await firstValueFrom(this.userService.loadPreferences()); + if (prefs) { + if (prefs.defaultProvider) this.instances.setSelectedProvider(prefs.defaultProvider as any); + if (prefs.region) this.instances.setRegion(prefs.region); + try { + const t = prefs.theme || 'system'; + document.documentElement.setAttribute('data-theme', t); + this.currentTheme.set(t); + localStorage.setItem('newtube.theme', t); + } catch {} + if (prefs.language) this.i18n.setLanguage(prefs.language); + } + this.closeModals(); + } catch (e: any) { + const status = (e && typeof e.status === 'number') ? e.status : 0; + const serverMsg = (e && e.error && (e.error.error || e.error.message)) || null; + if (status === 401) this.authError.set(serverMsg || 'Invalid credentials.'); + else if (status === 429) this.authError.set('Too many attempts. Please wait a minute and try again.'); + else this.authError.set(serverMsg || 'Login failed.'); + } + } + + async onSubmitRegister(ev: Event, ru?: HTMLInputElement, re?: HTMLInputElement, rp?: HTMLInputElement) { + ev.preventDefault(); + this.authError.set(null); + try { + const usernameRaw = (ru?.value ?? this.registerUsername()).trim(); + const emailRaw = (re?.value ?? this.registerEmail()).trim(); + const password = (rp?.value ?? this.registerPassword()); + const username = usernameRaw || emailRaw; // fallback to email when username empty + if (!username || !password) { + this.authError.set('Username (or Email) and password are required.'); + return; + } + await firstValueFrom(this.auth.register(username, password, emailRaw || undefined)); + const prefs = await firstValueFrom(this.userService.loadPreferences()); + if (prefs) { + if (prefs.defaultProvider) this.instances.setSelectedProvider(prefs.defaultProvider as any); + if (prefs.region) this.instances.setRegion(prefs.region); + try { + const t = prefs.theme || 'system'; + document.documentElement.setAttribute('data-theme', t); + this.currentTheme.set(t); + localStorage.setItem('newtube.theme', t); + } catch {} + } + this.closeModals(); + } catch (e: any) { + const status = (e && typeof e.status === 'number') ? e.status : 0; + const serverMsg = (e && e.error && (e.error.error || e.error.message)) || null; + if (status === 409) this.authError.set(serverMsg || 'Username already exists. Choose another.'); + else if (status === 400) this.authError.set(serverMsg || 'Username and password are required.'); + else if (status === 429) this.authError.set('Too many attempts. Please wait a minute and try again.'); + else this.authError.set(serverMsg || 'Registration failed.'); + } + } + + async onLogout() { + try { await firstValueFrom(this.auth.logout()); } catch {} + } +} diff --git a/src/components/home/home.component.html b/src/components/home/home.component.html new file mode 100644 index 0000000..06005f4 --- /dev/null +++ b/src/components/home/home.component.html @@ -0,0 +1,57 @@ +
+

{{ 'home.trending' | t }}

+ @if (notice()) { +
+ {{ notice() }} +
+ } + + @if (loading()) { +
+ @for (item of [1,2,3,4,5,6,7,8]; track item) { +
+
+
+
+
+
+
+ } +
+ } @else { + + + + @if (busyMore()) { +
+ + {{ 'loading.more' | t }} +
+ } + } +
+ diff --git a/src/components/home/home.component.ts b/src/components/home/home.component.ts new file mode 100644 index 0000000..cd574cd --- /dev/null +++ b/src/components/home/home.component.ts @@ -0,0 +1,126 @@ + +import { ChangeDetectionStrategy, Component, effect, inject, signal, untracked } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterLink } from '@angular/router'; +import { YoutubeApiService } from '../../services/youtube-api.service'; +import { Video } from '../../models/video.model'; +import { InstanceService } from '../../services/instance.service'; +import { InfiniteAnchorComponent } from '../shared/infinite-anchor/infinite-anchor.component'; +import { formatRelativeFr } from '../../utils/date.util'; +import { TranslatePipe } from '../../pipes/translate.pipe'; + +@Component({ + selector: 'app-home', + templateUrl: './home.component.html', + standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule, RouterLink, InfiniteAnchorComponent, TranslatePipe] +}) +export class HomeComponent { + private apiService = inject(YoutubeApiService); + private instances = inject(InstanceService); + + trendingVideos = signal([]); + loading = signal(true); + busyMore = signal(false); + nextCursor = signal(null); + notice = signal(null); + + constructor() { + this.reloadTrending(); + // React to provider/region changes to refresh trending automatically + effect(() => { + // Rerun when these signals change + const provider = this.instances.selectedProvider(); + const region = this.instances.region(); + const ptInstance = this.instances.activePeerTubeInstance(); + + // Reset notice and trigger reload, but without re-triggering the effect + untracked(() => { + this.notice.set(null); + this.reloadTrending(); + }); + }, { allowSignalWrites: true }); + } + + reloadTrending() { + const readiness = this.instances.getProviderReadiness(); + if (!readiness.ready) { + this.notice.set(readiness.reason || 'Le provider sélectionné n\'est pas prêt.'); + this.trendingVideos.set([]); + this.nextCursor.set(null); + this.loading.set(false); + return; + } + this.loading.set(true); + this.trendingVideos.set([]); + this.nextCursor.set(null); + // Important: reset busy flag so a previous pending state doesn't block new loads + this.busyMore.set(false); + this.fetchNextPage(); + } + + fetchNextPage() { + if (this.busyMore()) return; + const readiness = this.instances.getProviderReadiness(); + if (!readiness.ready) { + if (!this.notice()) this.notice.set(readiness.reason || 'Le provider sélectionné n\'est pas prêt.'); + return; + } + this.busyMore.set(true); + this.apiService.getTrendingPage(this.nextCursor()).subscribe(res => { + const merged = [...this.trendingVideos(), ...res.items]; + this.trendingVideos.set(merged); + this.nextCursor.set(res.nextCursor || null); + this.busyMore.set(false); + this.loading.set(false); + const provider = this.instances.selectedProvider(); + if (merged.length === 0 && !this.notice()) { + const readiness2 = this.instances.getProviderReadiness(); + if (!readiness2.ready) { + this.notice.set(readiness2.reason || 'Le provider sélectionné n\'est pas prêt.'); + } else if (provider === 'youtube') { + this.notice.set('Aucune vidéo tendance YouTube chargée. Vérifiez que votre YOUTUBE_API_KEY est valide et que les restrictions HTTP referrer incluent http://localhost:4200/*.'); + } else if (provider === 'peertube') { + const inst = this.instances.activePeerTubeInstance(); + this.notice.set(`PeerTube: les vidéos ne sont pas disponibles depuis l'instance "${inst}" pour le moment. Essayez une autre instance dans l'en-tête.`); + } else if (provider === 'rumble') { + const label = this.instances.selectedProviderLabel(); + this.notice.set(`Les vidéos ne sont pas disponibles pour le provider "${label}" pour le moment. Réessayez plus tard ou choisissez un autre provider.`); + } + } + }); + } + + formatViews(views: number): string { + if (views >= 1_000_000_000) { + return (views / 1_000_000_000).toFixed(1) + 'B'; + } + if (views >= 1_000_000) { + return (views / 1_000_000).toFixed(1) + 'M'; + } + if (views >= 1_000) { + return (views / 1_000).toFixed(1) + 'K'; + } + return views.toString(); + } + + // Relative date for cards (e.g., "il y a 2 heures") + formatRelative(dateIso?: string): string { + if (!dateIso) return ''; + return formatRelativeFr(dateIso); + } + + // Build query params for Watch page (provider + optional odysee slug) + watchQueryParams(v: Video): Record | null { + const p = this.instances.selectedProvider(); + const qp: any = { p }; + if (p === 'odysee' && v.url?.startsWith('https://odysee.com/')) { + let slug = v.url.substring('https://odysee.com/'.length); + if (slug.startsWith('/')) slug = slug.slice(1); + qp.slug = slug; + } + return qp; + } +} + diff --git a/src/components/info/utilisation/utilisation.component.html b/src/components/info/utilisation/utilisation.component.html new file mode 100644 index 0000000..0da563b --- /dev/null +++ b/src/components/info/utilisation/utilisation.component.html @@ -0,0 +1,119 @@ +
+

🧭 Guide d'utilisation

+ +
+ +
+
+

👋 Bienvenue sur NewTube

+

Cette page explique comment utiliser le site, découvrir des contenus, gérer vos préférences et tirer le meilleur parti des fournisseurs comme PeerTube, YouTube, Twitch, etc. 🎬

+
+
+

Utilisez le panneau de navigation à gauche pour accéder rapidement aux thèmes, aux tendances, à vos abonnements et à cette page d'aide. 🧰

+
    +
  • 🏠 Accueil — contenus populaires selon le thème sélectionné.
  • +
  • 🎞️ Shorts — vidéos courtes dans un lecteur optimisé.
  • +
  • 📚 Bibliothèque — playlists, vidéos aimées et abonnements.
  • +
  • ⚙️ Compte — préférences, historique et gestion des sessions.
  • +
+
+
+
🔍
+
Recherchez et explorez par thèmes
+
+
+
🧩
+
Choisissez un fournisseur (YouTube, PeerTube...)
+
+
+
🎛️
+
Personnalisez vos préférences
+
+
+
+
+ + +
+
+

🔎 Rechercher des vidéos

+

Cherchez sur plusieurs plateformes depuis une seule barre de recherche.

+
+
+
    +
  • ⌨️ Tapez votre requête et appuyez sur Entrée.
  • +
  • 🏷️ Filtrez par thèmes via la barre située sous l'en-tête.
  • +
  • ▶️ Ouvrez une vidéo pour afficher la page de lecture et les actions.
  • +
+
+ 💡 Astuce : combinez un thème et un mot-clé (ex. : « Tech IA ») pour des résultats plus pertinents. +
+
+
+ + +
+
+

🧩 Thèmes et Fournisseurs

+

Parcourez par centres d'intérêt et choisissez un fournisseur de contenus.

+
+
+
    +
  • 🧭 Explorer — liste de thèmes (Sport, Tech, Jeux, etc.).
  • +
  • 🎥 Fournisseurs — YouTube, Dailymotion, Twitch, Rumble, Odysee et PeerTube.
  • +
  • 🟠 PeerTube — gérez et basculez entre vos instances dans les Préférences.
  • +
+
+
+ + +
+
+
+

🟠 Trouver des instances PeerTube

+

Découvrez de nouvelles instances PeerTube publiques et actives.

+
+ Ouvrir joinpeertube.org ↗️ +
+
+

Une instance PeerTube est un serveur hébergeant des vidéos. Vous pouvez en ajouter plusieurs dans Compte → Préférences → PeerTube puis choisir celle active. Pour en trouver, consultez le répertoire des instances.

+
+
+ + +
+
+

🔐 Confidentialité et paramètres

+

Personnalisez votre expérience dans la page Préférences.

+
+
+
    +
  • 🌐 Choisissez votre langue, thème visuel et qualité vidéo par défaut.
  • +
  • 🎯 Définissez un fournisseur par défaut et gérez vos instances PeerTube.
  • +
  • 🕑 Consultez et effacez l'historique de visionnage dans Compte → Historique.
  • +
+
+ ⚠️ Conseil : si une instance PeerTube est lente, essayez d'en définir une autre comme active. +
+
+
+ + +
+
+

🆘 Besoin d'aide ?

+

Signalez un problème ou consultez le code source.

+
+
+

Le dépôt du projet est disponible sur notre instance Gitea :

+

+ + + Ouvrir Gitea ↗️ + +

+
+
+
+
diff --git a/src/components/info/utilisation/utilisation.component.ts b/src/components/info/utilisation/utilisation.component.ts new file mode 100644 index 0000000..455604a --- /dev/null +++ b/src/components/info/utilisation/utilisation.component.ts @@ -0,0 +1,11 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-utilisation', + standalone: true, + imports: [CommonModule], + templateUrl: './utilisation.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class UtilisationComponent {} diff --git a/src/components/library/liked/liked.component.html b/src/components/library/liked/liked.component.html new file mode 100644 index 0000000..1c57637 --- /dev/null +++ b/src/components/library/liked/liked.component.html @@ -0,0 +1,6 @@ +
+

Vidéos que vous aimez

+
+

Ici apparaîtront vos vidéos aimées (tous providers). Fonctionnalité à venir.

+
+
diff --git a/src/components/library/liked/liked.component.ts b/src/components/library/liked/liked.component.ts new file mode 100644 index 0000000..cb2c7f2 --- /dev/null +++ b/src/components/library/liked/liked.component.ts @@ -0,0 +1,11 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-library-liked', + standalone: true, + imports: [CommonModule], + templateUrl: './liked.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class LikedComponent { } diff --git a/src/components/library/playlists/playlists.component.html b/src/components/library/playlists/playlists.component.html new file mode 100644 index 0000000..3d4bf94 --- /dev/null +++ b/src/components/library/playlists/playlists.component.html @@ -0,0 +1,6 @@ +
+

Listes de lecture

+
+

Bientôt disponible: vos listes de lecture centralisées, tous providers confondus.

+
+
diff --git a/src/components/library/playlists/playlists.component.ts b/src/components/library/playlists/playlists.component.ts new file mode 100644 index 0000000..e47ebec --- /dev/null +++ b/src/components/library/playlists/playlists.component.ts @@ -0,0 +1,11 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-library-playlists', + standalone: true, + imports: [CommonModule], + templateUrl: './playlists.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PlaylistsComponent { } diff --git a/src/components/library/subscriptions/subscriptions.component.html b/src/components/library/subscriptions/subscriptions.component.html new file mode 100644 index 0000000..3da6be3 --- /dev/null +++ b/src/components/library/subscriptions/subscriptions.component.html @@ -0,0 +1,6 @@ +
+

Abonnements

+
+

Section pour suivre vos abonnements (à implémenter). Vous verrez ici les dernières vidéos des chaînes suivies sur chaque provider.

+
+
diff --git a/src/components/library/subscriptions/subscriptions.component.ts b/src/components/library/subscriptions/subscriptions.component.ts new file mode 100644 index 0000000..5b20808 --- /dev/null +++ b/src/components/library/subscriptions/subscriptions.component.ts @@ -0,0 +1,11 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-library-subscriptions', + standalone: true, + imports: [CommonModule], + templateUrl: './subscriptions.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class SubscriptionsComponent { } diff --git a/src/components/search/search.component.html b/src/components/search/search.component.html new file mode 100644 index 0000000..deecd6b --- /dev/null +++ b/src/components/search/search.component.html @@ -0,0 +1,151 @@ +
+

{{ pageHeading() }}

+ + @if (notice()) { +
+ {{ notice() }} +
+ } + + @if (!hasQuery()) { +

{{ 'search.hint' | t }}

+ } + + @if (hasQuery() && availableTags().length > 0) { +
+ @for (tag of availableTags(); track tag.key) { + + } +
+ } + + @if (loading()) { +
+ @for (item of [1,2,3,4,5,6,7,8]; track item) { +
+
+
+
+
+
+
+ } +
+ } @else if (selectedProviderForView() === 'twitch') { + +
+ +
+

Chaînes en direct

+ @if (twitchChannels().length > 0) { + + @if (twitchCursorChannels()) { +
+ +
+ } + } @else { +

Aucune chaîne en direct trouvée.

+ } +
+ + +
+

Vidéos (VOD)

+ @if (twitchVods().length > 0) { + + @if (twitchCursorVods()) { +
+ +
+ } + } @else { +

Aucune vidéo VOD trouvée.

+ } +
+
+ } @else if (results().length > 0) { + + + + @if (busyMore()) { +
+ + {{ 'loading.more' | t }} +
+ } + } @else if (hasQuery()) { +

{{ 'search.noResults' | t }}

+ } +
diff --git a/src/components/search/search.component.ts b/src/components/search/search.component.ts new file mode 100644 index 0000000..708fa06 --- /dev/null +++ b/src/components/search/search.component.ts @@ -0,0 +1,359 @@ +import { ChangeDetectionStrategy, Component, computed, effect, inject, signal, untracked } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ActivatedRoute, RouterLink } from '@angular/router'; +import { YoutubeApiService } from '../../services/youtube-api.service'; +import { Video } from '../../models/video.model'; +import { InfiniteAnchorComponent } from '../shared/infinite-anchor/infinite-anchor.component'; +import { formatRelativeFr } from '../../utils/date.util'; +import { InstanceService, Provider } from '../../services/instance.service'; +import { HistoryService } from '../../services/history.service'; +import { Title } from '@angular/platform-browser'; +import { TranslatePipe } from '../../pipes/translate.pipe'; + +@Component({ + selector: 'app-search', + standalone: true, + templateUrl: './search.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule, RouterLink, InfiniteAnchorComponent, TranslatePipe] +}) +export class SearchComponent { + private route = inject(ActivatedRoute); + private api = inject(YoutubeApiService); + private instances = inject(InstanceService); + private history = inject(HistoryService); + private title = inject(Title); + + q = signal(''); + loading = signal(false); + results = signal([]); + busyMore = signal(false); + nextCursor = signal(null); + // Twitch-specific dual lists + twitchChannels = signal([]); + twitchVods = signal([]); + twitchCursorChannels = signal(null); + twitchCursorVods = signal(null); + twitchBusyChannels = signal(false); + twitchBusyVods = signal(false); + notice = signal(null); + providerParam = signal(null); + themeParam = signal(null); + + hasQuery = computed(() => this.q().length > 0); + providerLabel = computed(() => { + const param = this.providerParam(); + if (param) { + const p = this.instances.providers().find(p => p.id === param); + return p?.label || param; + } + return this.instances.selectedProviderLabel(); + }); + pageHeading = computed(() => `Search - ${this.providerLabel()}${this.q() ? ' - ' + this.q() : ''}`); + // Public computed used by the template to avoid referencing private `instances` + selectedProviderForView = computed(() => this.providerParam() || this.instances.selectedProvider()); + + // Active tag filter. For non-Twitch providers: 'all' | 'short' | 'medium' | 'long' | 'recent'. + // For Twitch provider: 'twitch_all' | 'twitch_live' | 'twitch_vod'. + filterTag = signal('all'); + + // Helper computed: filtered list based on active tag (non-Twitch only) + filteredResults = computed(() => { + const tag = this.filterTag(); + const provider = this.selectedProviderForView(); + const list = this.results(); + if (provider === 'twitch') return list; // Not used for Twitch (separate sections) + if (tag === 'all') return list; + + const now = Date.now(); + const oneDay = 24 * 60 * 60 * 1000; + const sevenDays = 7 * oneDay; + const thirtyDays = 30 * oneDay; + const oneYear = 365 * oneDay; + + // Duration filters + if (tag === 'short') return list.filter(v => { + const d = Number(v.duration || 0); + return d > 0 && d < 4 * 60; + }); + if (tag === 'medium') return list.filter(v => { + const d = Number(v.duration || 0); + return d >= 4 * 60 && d < 20 * 60; + }); + if (tag === 'long') return list.filter(v => { + const d = Number(v.duration || 0); + return d >= 20 * 60; + }); + + // Date filters + if (tag === 'today') return list.filter(v => { + const uploadTime = typeof v.uploaded === 'number' ? v.uploaded : 0; + return uploadTime > 0 && (now - uploadTime) <= oneDay; + }); + if (tag === 'this_week') return list.filter(v => { + const uploadTime = typeof v.uploaded === 'number' ? v.uploaded : 0; + return uploadTime > 0 && (now - uploadTime) <= sevenDays; + }); + if (tag === 'this_month') return list.filter(v => { + const uploadTime = typeof v.uploaded === 'number' ? v.uploaded : 0; + return uploadTime > 0 && (now - uploadTime) <= thirtyDays; + }); + if (tag === 'this_year') return list.filter(v => { + const uploadTime = typeof v.uploaded === 'number' ? v.uploaded : 0; + return uploadTime > 0 && (now - uploadTime) <= oneYear; + }); + + return list; + }); + + // Available tags computed from current results (only show tags that can apply) + availableTags = computed(() => { + const provider = this.selectedProviderForView(); + const tags: { key: string; label: string; show: boolean }[] = []; + const now = Date.now(); + const list = this.results(); + + if (provider === 'twitch') { + const hasLive = this.twitchChannels().length > 0; + const hasVods = this.twitchVods().length > 0; + // Show the group if at least one of the sections is available + if (hasLive || hasVods) { + tags.push({ key: 'twitch_all', label: 'Tout', show: hasLive && hasVods }); + tags.push({ key: 'twitch_live', label: 'En direct', show: hasLive }); + tags.push({ key: 'twitch_vod', label: 'VOD', show: hasVods }); + } + return tags.filter(t => t.show); + } + + // Non-Twitch providers: duration + date filters + const oneDay = 24 * 60 * 60 * 1000; + const sevenDays = 7 * oneDay; + const thirtyDays = 30 * oneDay; + const oneYear = 365 * oneDay; + + let hasShort = false, hasMedium = false, hasLong = false, + hasToday = false, hasThisWeek = false, hasThisMonth = false, hasThisYear = false; + + for (const v of list) { + const d = Number(v.duration || 0); + const uploadTime = typeof v.uploaded === 'number' ? v.uploaded : 0; + const timeDiff = now - uploadTime; + + // Duration filters + if (d > 0 && d < 4 * 60) hasShort = true; + else if (d >= 4 * 60 && d < 20 * 60) hasMedium = true; + else if (d >= 20 * 60) hasLong = true; + + // Date filters + if (uploadTime > 0) { + if (timeDiff <= oneDay) hasToday = true; + if (timeDiff <= sevenDays) hasThisWeek = true; + if (timeDiff <= thirtyDays) hasThisMonth = true; + if (timeDiff <= oneYear) hasThisYear = true; + } + } + + // Add duration filters + tags.push({ key: 'all', label: 'Tout', show: list.length > 0 }); + tags.push({ key: 'short', label: 'Moins de 4 min', show: hasShort }); + tags.push({ key: 'medium', label: 'De 4 à 20 min', show: hasMedium }); + tags.push({ key: 'long', label: '20 min et plus', show: hasLong }); + + // Add date filters + tags.push({ key: 'today', label: 'Aujourd\'hui', show: hasToday }); + tags.push({ key: 'this_week', label: 'Cette semaine', show: hasThisWeek }); + tags.push({ key: 'this_month', label: 'Ce mois-ci', show: hasThisMonth }); + tags.push({ key: 'this_year', label: 'Cette année', show: hasThisYear }); + + return tags.filter(t => t.show); + }); + + constructor() { + // Update document title when provider or query changes + effect(() => { + this.title.setTitle(this.pageHeading()); + }); + + // Listen to query param changes (so subsequent searches update) + this.route.queryParamMap.subscribe((pm) => { + const q = (pm.get('q') || '').trim(); + this.q.set(q); + const prov = (pm.get('provider') as Provider) || null; + const theme = pm.get('theme'); + this.providerParam.set(prov); + this.themeParam.set(theme); + if (q) { + this.notice.set(null); + // Reset active tag on new query + const provider = (prov || this.instances.selectedProvider()); + this.filterTag.set(provider === 'twitch' ? 'twitch_all' : 'all'); + this.reloadSearch(); + } else { + this.results.set([]); + this.nextCursor.set(null); + this.loading.set(false); + } + }); + + // React to provider/region/PeerTube instance changes to refresh search automatically + effect(() => { + const provider = this.instances.selectedProvider(); + const region = this.instances.region(); + const ptInstance = this.instances.activePeerTubeInstance(); + + untracked(() => { + // If provider is explicitly specified in query, do not override it with global changes + if (this.providerParam()) return; + if (this.q()) { + this.notice.set(null); + this.reloadSearch(); + } + }); + }, { allowSignalWrites: true }); + } + + reloadSearch() { + const readiness = this.instances.getProviderReadiness(this.providerParam() || undefined as any); + if (!readiness.ready) { + this.notice.set(readiness.reason || 'Le provider sélectionné n\'est pas prêt.'); + this.results.set([]); + this.nextCursor.set(null); + this.twitchChannels.set([]); + this.twitchVods.set([]); + this.twitchCursorChannels.set(null); + this.twitchCursorVods.set(null); + this.loading.set(false); + return; + } + this.loading.set(true); + this.results.set([]); + this.nextCursor.set(null); + this.twitchChannels.set([]); + this.twitchVods.set([]); + this.twitchCursorChannels.set(null); + this.twitchCursorVods.set(null); + const provider = this.providerParam() || this.instances.selectedProvider(); + // Record search term with provider once per reload + try { + this.history.recordSearch(this.q(), { provider }).subscribe({ + next: () => {}, + error: (err) => console.error('Error recording search:', err) + }); + } catch (err) { + console.error('Error in recordSearch:', err); + } + // Ensure default tag matches provider + this.filterTag.set(provider === 'twitch' ? 'twitch_all' : 'all'); + if (provider === 'twitch') { + // Load both sections in parallel + this.twitchBusyChannels.set(true); + this.twitchBusyVods.set(true); + this.api.searchTwitchChannelsPage(this.q(), null).subscribe(res => { + this.twitchChannels.set(res.items); + this.twitchCursorChannels.set(res.nextCursor || null); + this.twitchBusyChannels.set(false); + this.loading.set(false); + }); + this.api.searchTwitchVodsPage(this.q(), null).subscribe(res => { + this.twitchVods.set(res.items); + this.twitchCursorVods.set(res.nextCursor || null); + this.twitchBusyVods.set(false); + this.loading.set(false); + }); + } else { + this.fetchNextPage(); + } + } + + fetchNextPage() { + if (this.busyMore() || !this.q()) return; + const readiness = this.instances.getProviderReadiness(this.providerParam() || undefined as any); + if (!readiness.ready) { + if (!this.notice()) this.notice.set(readiness.reason || 'Le provider sélectionné n\'est pas prêt.'); + return; + } + this.busyMore.set(true); + const providerOverride = this.providerParam(); + this.api.searchVideosPage(this.q(), this.nextCursor(), providerOverride as any).subscribe(res => { + const merged = [...this.results(), ...res.items]; + this.results.set(merged); + this.nextCursor.set(res.nextCursor || null); + this.busyMore.set(false); + this.loading.set(false); + // Provider/instance availability notices (avoid overriding legitimate no-results unless clear) + if (merged.length === 0 && !this.notice()) { + const readiness2 = this.instances.getProviderReadiness(); + if (!readiness2.ready) { + this.notice.set(readiness2.reason || 'Le provider sélectionné n\'est pas prêt.'); + } else { + const provider = this.providerParam() || this.instances.selectedProvider(); + if (provider === 'peertube') { + const inst = this.instances.activePeerTubeInstance(); + this.notice.set(`PeerTube: les vidéos ne sont pas disponibles depuis l'instance "${inst}" pour le moment. Essayez une autre instance dans l'en-tête.`); + } else if (provider === 'rumble') { + const label = this.instances.selectedProviderLabel(); + this.notice.set(`Les vidéos ne sont pas disponibles pour le provider "${label}" pour le moment. Réessayez plus tard ou choisissez un autre provider.`); + } + } + } + }); + } + + loadMoreTwitchChannels() { + if (this.twitchBusyChannels() || !this.twitchCursorChannels()) return; + this.twitchBusyChannels.set(true); + this.api.searchTwitchChannelsPage(this.q(), this.twitchCursorChannels()).subscribe(res => { + this.twitchChannels.set([...this.twitchChannels(), ...res.items]); + this.twitchCursorChannels.set(res.nextCursor || null); + this.twitchBusyChannels.set(false); + }); + } + + loadMoreTwitchVods() { + if (this.twitchBusyVods() || !this.twitchCursorVods()) return; + this.twitchBusyVods.set(true); + this.api.searchTwitchVodsPage(this.q(), this.twitchCursorVods()).subscribe(res => { + this.twitchVods.set([...this.twitchVods(), ...res.items]); + this.twitchCursorVods.set(res.nextCursor || null); + this.twitchBusyVods.set(false); + }); + } + + formatViews(views: number): string { + if (views >= 1_000_000_000) return (views / 1_000_000_000).toFixed(1) + 'B'; + if (views >= 1_000_000) return (views / 1_000_000).toFixed(1) + 'M'; + if (views >= 1_000) return (views / 1_000).toFixed(1) + 'K'; + return views.toString(); + } + + formatRelative(dateIso?: string): string { + if (!dateIso) return ''; + return formatRelativeFr(dateIso); + } + + // Build query params for Watch page (provider + optional odysee slug) + watchQueryParams(v: Video): Record | null { + const p = this.providerParam() || this.instances.selectedProvider(); + const qp: any = { p }; + if (p === 'odysee' && v.url?.startsWith('https://odysee.com/')) { + let slug = v.url.substring('https://odysee.com/'.length); + if (slug.startsWith('/')) slug = slug.slice(1); + qp.slug = slug; + } + if (p === 'twitch' && v.type === 'channel') { + // Extract channel login from uploaderUrl if available + const url = v.uploaderUrl || v.url || ''; + try { + const u = new URL(url); + const parts = u.pathname.split('/').filter(Boolean); + if (parts.length > 0) qp.channel = parts[0]; + } catch {} + } + return qp; + } + + // Update active filter tag from the template + setFilterTag(key: string) { + this.filterTag.set(key); + } +} diff --git a/src/components/shared/infinite-anchor/infinite-anchor.component.html b/src/components/shared/infinite-anchor/infinite-anchor.component.html new file mode 100644 index 0000000..fb78333 --- /dev/null +++ b/src/components/shared/infinite-anchor/infinite-anchor.component.html @@ -0,0 +1,5 @@ +
+
+ +
+
diff --git a/src/components/shared/infinite-anchor/infinite-anchor.component.ts b/src/components/shared/infinite-anchor/infinite-anchor.component.ts new file mode 100644 index 0000000..d700264 --- /dev/null +++ b/src/components/shared/infinite-anchor/infinite-anchor.component.ts @@ -0,0 +1,42 @@ +import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, OnDestroy, Output, ViewChild } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-infinite-anchor', + standalone: true, + templateUrl: './infinite-anchor.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule] +}) +export class InfiniteAnchorComponent implements AfterViewInit, OnDestroy { + @ViewChild('sentinel', { static: true }) sentinelRef!: ElementRef; + + @Input() disabled = false; + @Input() busy = false; + @Input() rootMargin = '300px 0px 300px 0px'; + @Input() threshold: number | number[] = 0.01; + + @Output() loadMore = new EventEmitter(); + + private observer?: IntersectionObserver; + + ngAfterViewInit(): void { + this.observer = new IntersectionObserver((entries) => { + for (const entry of entries) { + if (entry.isIntersecting && !this.disabled && !this.busy) { + this.loadMore.emit(); + } + } + }, { + root: null, + rootMargin: this.rootMargin, + threshold: this.threshold, + }); + + this.observer.observe(this.sentinelRef.nativeElement); + } + + ngOnDestroy(): void { + this.observer?.disconnect(); + } +} diff --git a/src/components/shorts/watch-short.component.html b/src/components/shorts/watch-short.component.html new file mode 100644 index 0000000..df6248c --- /dev/null +++ b/src/components/shorts/watch-short.component.html @@ -0,0 +1,52 @@ +
+ +
+ +
+ @if (embedUrl(); as url) { + + } @else if (loading()) { +
+ } @else if (error()) { +
+ {{ error() }} +
+ } + + + @if (current(); as v) { +
+
+ +
+
{{ v.title }}
+
@{{ v.uploaderName }}
+
+
+
+ } +
+ + + + + + +
+ + +
+
+
diff --git a/src/components/shorts/watch-short.component.ts b/src/components/shorts/watch-short.component.ts new file mode 100644 index 0000000..3634888 --- /dev/null +++ b/src/components/shorts/watch-short.component.ts @@ -0,0 +1,267 @@ +import { ChangeDetectionStrategy, Component, computed, inject, signal, HostListener } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; +import { firstValueFrom } from 'rxjs'; +import { YoutubeApiService } from '../../services/youtube-api.service'; +import { InstanceService } from '../../services/instance.service'; +import { Video } from '../../models/video.model'; + +@Component({ + selector: 'app-watch-short', + standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule], + templateUrl: './watch-short.component.html' +}) +export class WatchShortComponent { + private api = inject(YoutubeApiService); + private instances = inject(InstanceService); + private sanitizer = inject(DomSanitizer); + + loading = signal(true); + error = signal(null); + items = signal([]); + index = signal(0); + nextCursor = signal(null); + busyMore = signal(false); + + // scroll/swipe helpers + private wheelAccum = 0; + private lastSwipeY: number | null = null; + private lastScrollTs = 0; + + readonly provider = computed(() => this.instances.selectedProvider()); + readonly current = computed